ios - 如何在 Swift 3 中将核心数据导出为 CSV?

标签 ios swift csv core-data export

我想导出我的实体“日志”的所有数据。我找到了这个代码示例: https://gist.github.com/kenechilearnscode/2d5d35f550f593332319 但这对我不起作用。它不添加核心数据的数据,我得到的唯一输出是:“这是应用程序将导出的内容:日期、标签、类型” 我的核心数据实体是“日志”,具有以下属性:date(type:date)、labe1(type:String) 和 typ(type:Double)。 如何将核心数据导出到 CSV 文件并通过邮件发送? 感谢您的帮助:)

var logs : [Log] = []

func createExportString() -> String {


    var date: NSDate? = NSDate()
    var labe1: String?
    var typ: Double

    var export: String = NSLocalizedString("date, label, typ, \n", comment: "")


    for (index, log) in logs.enumerated() {
        if index < logs.count - 1 {

            date = Date() as? NSDate
            label =  log.value(forKey: "time") as? String
            typ = (log.value(forKey: "type") as? Double)!


            let dateString = "\(log.date!)"
            let labelString = "\(log.labe1!)"
            let typeString = "\(log.typ)"

            export += dateString + "," + labelString + "," + typeString + "," + "\n"
        }
    }
    print("This is what the app will export: \(export)")
    return export
}

func exportDatabase() {
    var exportString = createExportString()
    saveAndExport(exportString: exportString)
}


    func saveAndExport(exportString: String) {
        let exportFilePath = NSTemporaryDirectory() + "export.csv"
        let exportFileURL = NSURL(fileURLWithPath: exportFilePath)
        FileManager.default.createFile(atPath: exportFilePath, contents: NSData() as Data, attributes: nil)
        var fileHandleError: NSError? = nil
        var fileHandle: FileHandle? = nil
        do {
            fileHandle = try FileHandle(forWritingTo: exportFileURL as URL)
        } catch {
            print("Error with fileHandle")
        }

        if fileHandle != nil {
            fileHandle!.seekToEndOfFile()
            let csvData = exportString.data(using: String.Encoding.utf8, allowLossyConversion: false)
            fileHandle!.write(csvData!)

            fileHandle!.closeFile()

            let firstActivityItem = NSURL(fileURLWithPath: exportFilePath)
            let activityViewController : UIActivityViewController = UIActivityViewController(
                activityItems: [firstActivityItem], applicationActivities: nil)

            activityViewController.excludedActivityTypes = [
                UIActivityType.assignToContact,
                UIActivityType.saveToCameraRoll,
                UIActivityType.postToFlickr,
                UIActivityType.postToVimeo,
                UIActivityType.postToTencentWeibo
            ]

            self.present(activityViewController, animated: true, completion: nil)
        }
    }

编辑:

我尝试添加这些:

let context = DatabaseController.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Log")
    let result = try! NSManagedObjectContext.execute(fetchRequest)


    logs = [result]

但我收到错误消息:“在类型‘NSManagedObjectContext’上使用实例成员‘execute’;您的意思是要使用类型‘NSManagedObjectContext’的值吗?”

编辑 2:

有了这些:

    do {
        let results = try context.execute(fetchRequest)
    }
    catch {
        print(error)
    }

我在“logs = [result]: 使用未解析的标识符“结果”

最佳答案

这是我用于 Swift 4.2 的解决方案。

已更新以匹配存储库中的代码。

import UIKit
import CoreData

class ViewController: UIViewController {

    var itemid = 178
    var nametext = "Jones3"
    var amountDouble = 68
    var inventoryDate: Date? = Date()
    var stockStatus = true
    var fetchedStatsArray: [NSManagedObject] = []
    let context = CoreDataStack.context

    override func viewDidLoad() {
        super.viewDidLoad()
        // This add a new record every time the app is run
        storeTranscription()
        // Loads the current data
        getTranscriptions()
    }

    @IBAction func exportButton(_ sender: UIButton) {
        exportDatabase()
    }

    func storeTranscription() {
        //retrieve the entity that we just created
        let entity =  NSEntityDescription.entity(forEntityName: "ItemList", in: context)
        let transc = NSManagedObject(entity: entity!, insertInto: context) as! ItemList

        //set the entity values
        transc.itemID = Double(itemid)
        transc.productname = nametext
        transc.amount = Double(amountDouble)
        transc.stock = stockStatus
        transc.inventoryDate = inventoryDate

        //save the object
        do {
            try context.save()
            print("saved!")
        } catch let error as NSError  {
            print("Could not save \(error), \(error.userInfo)")
        } catch {

        }
    }

    func getTranscriptions () {
        //create a fetch request, telling it about the entity
        let fetchRequest: NSFetchRequest<ItemList> = ItemList.fetchRequest()

        do {
            //go get the results
            let searchResults = try context.fetch(fetchRequest)
            fetchedStatsArray = searchResults as [NSManagedObject]
            //I like to check the size of the returned results!
            print ("num of results = \(searchResults.count)")
            //You need to convert to NSManagedObject to use 'for' loops
            for trans in searchResults as [NSManagedObject] {
                //get the Key Value pairs (although there may be a better way to do that...
                print("\(trans.value(forKey: "productname")!)")
                let mdate = trans.value(forKey: "inventoryDate") as! Date
                print(mdate)
            }

        } catch {
            print("Error with request: \(error)")
        }
    }

    func exportDatabase() {
        let exportString = createExportString()
        saveAndExport(exportString: exportString)
    }

    func saveAndExport(exportString: String) {
        let exportFilePath = NSTemporaryDirectory() + "itemlist.csv"
        let exportFileURL = NSURL(fileURLWithPath: exportFilePath)
        FileManager.default.createFile(atPath: exportFilePath, contents: NSData() as Data, attributes: nil)
        //var fileHandleError: NSError? = nil
        var fileHandle: FileHandle? = nil
        do {
            fileHandle = try FileHandle(forWritingTo: exportFileURL as URL)
        } catch {
            print("Error with fileHandle")
        }

        if fileHandle != nil {
            fileHandle!.seekToEndOfFile()
            let csvData = exportString.data(using: String.Encoding.utf8, allowLossyConversion: false)
            fileHandle!.write(csvData!)

            fileHandle!.closeFile()

            let firstActivityItem = NSURL(fileURLWithPath: exportFilePath)
            let activityViewController : UIActivityViewController = UIActivityViewController(
                activityItems: [firstActivityItem], applicationActivities: nil)

            activityViewController.excludedActivityTypes = [
                UIActivity.ActivityType.assignToContact,
                UIActivity.ActivityType.saveToCameraRoll,
                UIActivity.ActivityType.postToFlickr,
                UIActivity.ActivityType.postToVimeo,
                UIActivity.ActivityType.postToTencentWeibo
            ]

            self.present(activityViewController, animated: true, completion: nil)
        }
    }

    func createExportString() -> String {
        var itemIDvar: NSNumber?
        var productNamevar: String?
        var amountvar: NSNumber?
        var stockvar: Bool?

        var export: String = NSLocalizedString("itemID, productName, Amount \n", comment: "")
        for (index, itemList) in fetchedStatsArray.enumerated() {
            if index <= fetchedStatsArray.count - 1 {
                itemIDvar = itemList.value(forKey: "itemID") as! NSNumber?
                productNamevar = itemList.value(forKey: "productname") as! String?
                amountvar = itemList.value(forKey: "amount") as! NSNumber?
                stockvar = itemList.value(forKey: "stock") as! Bool?
                let inventoryDatevar = itemList.value(forKey: "inventoryDate") as! Date
                let itemIDString = itemIDvar
                let procductNameSting = productNamevar
                let amountSting = amountvar
                let stockSting = stockvar
                let inventoryDateSting = "\(inventoryDatevar)"
                export += "\(itemIDString!),\(procductNameSting!),\(stockSting!),\(amountSting!),\(inventoryDateSting) \n"
            }
        }
        print("This is what the app will export: \(export)")
        return export
    }   
}

Project Files

关于ios - 如何在 Swift 3 中将核心数据导出为 CSV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40222530/

相关文章:

ios - 如何绘制与弧垂直相交的线(核心图形)?

Swift - SKSpriteNode 在默认位置从场景中丢失

php - CSV 导入过程中的特殊字符编码

python - 将两个 csv 文件与自定义列合并

ios - iPhone SDK : Play a single WAV from a button

ios - 需要有关以编程方式创建自动布局约束的帮助

ios - 从 objective-c 文件访问swift文件中的共享数据

python - Pandas:读取文件的头部和中间部分

ios - 在 RxSwift 中订阅 Observable 或 Driver 花费的时间太长

swift - header Logo 在 Swift 4/XCode 9/iOS 11 上大小错误