将记录保存到 CloudKit 时应用程序崩溃

Posted

技术标签:

【中文标题】将记录保存到 CloudKit 时应用程序崩溃【英文标题】:App crashes when saving record to CloudKit 【发布时间】:2017-01-28 03:31:34 【问题描述】:

我正在使用 CloudKit 来保存用户输入的记录,但是我的应用程序崩溃了。

下面是我的代码:

func saveRecordToCloud(_ pinpoint:Details!) -> Void 
    // Prepare the record to save
    let record = CKRecord(recordType: "Details")
    record.setValue(pinpoint.title, forKey: "title")
    record.setValue(pinpoint.location, forKey: "location")
    record.setValue(pinpoint.date, forKey: "date")

    // Resize the image
    let originalImage = UIImage(data: pinpoint.image as Data)!
    let scalingFactor = (originalImage.size.width > 1024) ? 1024 / originalImage.size.width : 1.0
    let scaledImage = UIImage(data: pinpoint.image as Data, scale: scalingFactor)!

    // Write the image to local file for temporary use
    let imageFilePath = NSTemporaryDirectory() + pinpoint.title
    try? UIImageJPEGRepresentation(scaledImage, 0.8)?.write(to: URL(fileURLWithPath: imageFilePath), options: [.atomic])

    // Create image asset for upload
    let imageFileURL = URL(fileURLWithPath: imageFilePath)
    let imageAsset = CKAsset(fileURL: imageFileURL)
    record.setValue(imageAsset, forKey: "image")


    // Get the Public iCloud Database
    let publicDatabase = CKContainer.default().publicCloudDatabase

    // Save the record to iCloud
    publicDatabase.save(record, completionHandler:  (record:CKRecord?, error:NSError?) -> Void  in
        // Remove temp file
        do 
            try FileManager.default.removeItem(atPath: imageFilePath)

         catch 
            print("Failed to save record to the cloud: \(error)")
        
         as! (CKRecord?, Error?) -> Void)

我收到的错误是:

线程 1:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)

这是 as! (CKRecord?, Error?) -> Void) 行,倒数第二行。

我正在使用 Swift 3.0

【问题讨论】:

哪一行导致崩溃? @Pierce 最后一行写着 as! (CKRecord?, Error?) -> Void)。我会将这个添加到问题中。 我知道它是什么 -> 我会发布答案。将您的项目从旧版本的 Swift 转换为 Swift 3 后是否发生这种情况? @Pierce 好的,谢谢。不,我没有转换它。 【参考方案1】:

当我将旧的 Swift 2.x 项目转换为 Swift 3 时,我遇到了同样的问题。他们采用 CloudKit 完成处理程序,而不是将它们转换为 Swift 3 - 它保留在 Swift 2 中,然后强制转换它作为 Swift 3 的 CKCompletionHandler。它总是会导致崩溃。从完成处理程序的末尾删除as! (CKRecord?, Error?) -> Void) 的行。然后返回到您的实际完成处理程序并将其更改为如下所示:

publicDatabase.save(record, completionHandler:  (record:CKRecord?, error: Error?) in
    // Remove temp file
    do 
        try FileManager.default.removeItem(atPath: imageFilePath)

     catch 
        print("Failed to save record to the cloud: \(error)")
    

基本上你只需将NSError 更改为Error,你就可以摆脱-> void (returns void) 行。这是多余的。让我知道这是否有效。

【讨论】:

完美!谢谢皮尔斯。 @AnnabelleSykes - 没问题...祝你好运!

以上是关于将记录保存到 CloudKit 时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将 CloudKit 记录保存到本地文件保存除 CKAsset 之外的所有字段

CloudKit 通知未发送到所有设备

Cloudkit 中的即时模式

将多个字段添加到 CloudKit 中的同一记录名称行

CoreData与CloudKit同步时将图像保存到CoreData?

如何将字典保存到cloudkit