i am trying to establish CSV importing to my project. so that when pressing on Import CSV button, it will give user option to choose file and processed to importing and save it to CoreData entity. But the problem is that, after choosing the file, it will give me the selected file name and File Read Successfull, and i am getting error (( Error the operation could not be completed. (Foundation._GenericObjCError error 0.) )). can please someone help me. i would appreciate it.
import SwiftUI
import CoreData
import UniformTypeIdentifiers
struct CSVImportView: View {
@State private var document: MessageDocument = MessageDocument(message: "Hello, World!")
@State private var fileContent: String = ""
@State private var errorMessage: String = ""
@State private var showAlert: Bool = false
@Environment(\.managedObjectContext) private var moc
@State private var isImporting: Bool = false
@State private var file: URL?
var body: some View {
NavigationView {
VStack {
Button("Import CSV") {
isImporting.toggle()
}
if let file = file {
Text("Selected File: \(file.lastPathComponent)")
Text(fileContent.isEmpty ? "Cannot read file" : "File Read Successfully")
.foregroundColor(fileContent.isEmpty ? .red : .green)
// Remove Import Button
GroupBox(label: Text("Message:")) {
TextEditor(text: $document.message)
}
}
}
.padding()
.navigationTitle("CSV Import")
}
.fileImporter(
isPresented: $isImporting,
allowedContentTypes: [.plainText],
allowsMultipleSelection: false
) { result in
do {
guard let selectedFile = try result.get().first else { return }
print("Selected File URL:", selectedFile) // Print the selected file URL
guard selectedFile.startAccessingSecurityScopedResource() else {
showAlertWithError(message: "Unable to access the selected file.")
return
}
defer { selectedFile.stopAccessingSecurityScopedResource() }
self.file = selectedFile
let fileContentData: Data
do {
fileContentData = try Data(contentsOf: selectedFile)
} catch let error {
showAlertWithError(message: "Error reading file content: \(error.localizedDescription)")
return
}
print("File Content:", fileContentData) // Print the file content after reading
guard let message = String(data: fileContentData, encoding: .utf8) else {
showAlertWithError(message: "Unable to read file content.")
return
}
document.message = message
fileContent = message
let parsedData = parseCSV(content: message)
let container = NoteCoreData.shared.persistentContainer
saveToCoreData(parsedData: parsedData, with: container) { success, message in
if success {
showAlert = true
errorMessage = message // Update message to indicate success
} else {
showAlert = true
errorMessage = message // Display error message
print("Error saving data:", message)
}
}
print("Parsed Data:", parsedData)
// importCSV(url: selectedFile)
} catch let fileError as NSError {
print("File error:", fileError.localizedDescription)
showAlertWithError(message: "File Error: \(fileError.localizedDescription)")
} catch {
showAlertWithError(message: error.localizedDescription)
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Error"), message: Text(errorMessage), dismissButton: .default(Text("OK")))
}
}
func importCSV(url: URL) {
do {
let content = try String(contentsOf: url, encoding: .utf8)
let parsedData = parseCSV(content: content)
let container = NoteCoreData.shared.persistentContainer
saveToCoreData(parsedData: parsedData, with: container) { success, message in
if success {
showAlert = true
errorMessage = message // Update message to indicate success
} else {
showAlert = true
errorMessage = message // Display error message
print("Error saving data:", message)
}
}
} catch {
showAlertWithError(message: error.localizedDescription)
}
}
func parseCSV(content: String) -> [Note] {
var parsedData: [Note] = []
let rows = content.components(separatedBy: "\n")
let possibleDateFormats = ["MM/dd/yyyy", "dd/MM/yyyy", "yyyy-MM-dd"]
for row in rows {
let columns = row.components(separatedBy: ",")
if columns.count >= 3 {
let title = columns[0]
let dateString = columns[1]
let noteContent = columns[2]
if let date = tryFixingDate(dateString, possibleDateFormats: possibleDateFormats) {
let note = Note()
note.title = title
note.date = date
note.noteContent = noteContent
parsedData.append(note)
} else {
print("Unable to convert date:", dateString)
}
} else if !row.isEmpty {
print("Incomplete row:", row)
}
}
return parsedData
}
func saveToCoreData(parsedData: [Note], with container: NSPersistentContainer, completion: @escaping (Bool, String) -> Void) {
let context = container.viewContext
for note in parsedData {
let newNote = Note(context: context)
newNote.userID = "UniqueUserID"
newNote.id = UUID()
newNote.title = note.title
newNote.date = note.date
newNote.noteContent = note.noteContent
newNote.dataType = "Note"
}
do {
try context.save()
completion(true, "Data saved successfully!") // Data saved successfully
} catch {
completion(false, error.localizedDescription) // Error occurred during saving
}
}
func tryFixingDate(_ dateString: String, possibleDateFormats: [String]) -> Date? {
let dateFormatter = DateFormatter()
for format in possibleDateFormats {
dateFormatter.dateFormat = format
if let parsedDate = dateFormatter.date(from: dateString) {
return parsedDate
}
}
return nil
}
// Function to show alert with error message
func showAlertWithError(message: String) {
errorMessage = message
showAlert = true
print("Error:", message)
}
}
struct MessageDocument: FileDocument {
static var readableContentTypes: [UTType] { [.plainText] }
var message: String
init(message: String) {
self.message = message
}
init(configuration: ReadConfiguration) throws {
guard let data = configuration.file.regularFileContents,
let string = String(data: data, encoding: .utf8)
else {
throw CocoaError(.fileReadCorruptFile)
}
message = string
}
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
return FileWrapper(regularFileWithContents: message.data(using: .utf8)!)
}
}




