A new app I’m working on has a Core Data back end and I wanted to implement a quick way to export all the entities into a CSV file and dump it into the Desktop.
Here are the snippets to do it:
1. Make sure you get the NSObjects you want to export (in this case I use a function that will return an array with the fetched NSObjectSubclass Transaction)
private func provideAllTransactions() -> Array<Transaction>{
let fetchRequest = NSFetchRequest(entityName: “Transaction”)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: “date”, ascending: false), NSSortDescriptor(key: “concept”, ascending: true)]
return try! managedObjectContext.executeFetchRequest(fetchRequest) as! Array<Transaction>
}
2. Convert to text, properly separating by commas and lines
private func convertTransactionsToCsvString(transactions: Array<Transaction>)->String{
var result = “HEADER 1, HEADER 2, HEADER 3, \r”//Headers
for transactionIterator in transactions{ //Data
result = result + “\”” + (transactionIterator.accountItBelongsTo?.name)! + “\”” + “,”
result = result + “\”” + ((transactionIterator.date)?.description)! ?? NSDate().description
result = result + “\”” + “,” + “\”” + (transactionIterator.concept)! + “\””
result = result + “\”” + “\r”
}
return result
}
3. Save to a path
func exportAllToCsv() -> Bool{
let contentsToWrite = convertTransactionsToCsvString(provideAllTransactions())
//Select path
let path = “/Users/USER_NAME/Desktop/csvTest.csv”
//Try to save it
do {
try contentsToWrite.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding)
}catch{
print(“ERROR: Export could not be saved in %”, path)
}
return true
}
Note that in this example the path is hardcoded to the desktop of the user named USER_NAME, you should have the user choose where he wants to save it or you can hardcode a location in your disk.
If you would have a NSDictionary it would be almost the same but starting at point 2 with the dictionary results.
Questions / comments? I’m at @MarcMasVi
Marc
PS. Here is how you would have the path be selected by the user:
privatefunc userToChooseAFileInModalPannel() -> String?{
let pannel: NSOpenPanel = NSOpenPanel()
pannel.canChooseDirectories = true
pannel.canChooseFiles = false
pannel.allowsMultipleSelection = false
pannel.runModal()
return pannel.URL?.path
}
then in point 3 you would do
//Select path
let path = userToChooseAFileInModalPannel() + “/test.csv”