如何使用Swift上传图片到CloudKit?

7

我该如何使用Swift上传和下载CloudKit中的图片?

我应该使用哪种属性类型?

enter image description here

我该使用哪些代码?以下是我目前正在使用的代码...

func SaveImageInCloud(ImageToSave: UIImage) {
        let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")
        newRecord.setValue(ImageToSave, forKey: "Image")

        if let database = self.privateDatabase {


            database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in

                if error != nil {

               NSLog(error.localizedDescription)

                }


                else {

                    dispatch_async(dispatch_get_main_queue()) {

println("finished")

                    }
                }
        })
        }
5个回答

5
您需要创建一个CKAsset并将其添加到您的记录中。您可以使用以下代码来完成:

你需要创建一个CKAsset并将其添加到你的记录中。你可以用下面这段代码实现:

func SaveImageInCloud(ImageToSave: UIImage) {
    let newRecord:CKRecord = CKRecord(recordType: "ImageRecord")

    let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
    let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
    if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
        if paths.count > 0 {
            if let dirPath = paths[0] as? String {
                let writePath = dirPath.stringByAppendingPathComponent("Image2.png")
                UIImagePNGRepresentation(ImageToSave).writeToFile(writePath, atomically: true)

                var File : CKAsset?  = CKAsset(fileURL: NSURL(fileURLWithPath: writePath))
                newRecord.setValue(File, forKey: "Image")

            }
        }
    }

    if let database = self.privateDatabase {
        database.saveRecord(newRecord, completionHandler: { (record:CKRecord!, error:NSError! ) in
            if error != nil {
                NSLog(error.localizedDescription)
            } else {
                dispatch_async(dispatch_get_main_queue()) {
                    println("finished")
                }
            }
        })
    }

2
这里有一个和Edwin的答案类似但更紧凑的方法。我测试过它并且运行良好。
这个例子将 UIImageView "myImage" 存储到 CKRecord "mySaveRecord" 中,只需将这些名称替换为您自己的即可。
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let imageFilePath = documentDirectory.stringByAppendingPathComponent("lastimage")
UIImagePNGRepresentation(myImage).writeToFile(imageFilePath, atomically: true)
let asset = CKAsset(fileURL: NSURL(fileURLWithPath: imageFilePath))
mySaveRecord.setObject(asset, forKey: "ProfilePicture")
CKContainer.defaultContainer().publicCloudDatabase.saveRecord(mySaveRecord, completionHandler: {
    record, error in
    if error != nil {
        println("\(error)")
    } else {
        //record saved successfully!
    }
})

2

我使用Swift 5创建了这个小扩展,用于将UIImage转换为CKAsset

extension UIImage {
    func toCKAsset(name: String? = nil) -> CKAsset? {
        guard let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else {
            return nil
        }

        guard let imageFilePath = NSURL(fileURLWithPath: documentDirectory)
                .appendingPathComponent(name ?? "asset#\(UUID.init().uuidString)")
        else {
            return nil
        }

        do {
            try self.pngData()?.write(to: imageFilePath)
            return CKAsset(fileURL: imageFilePath)
        } catch {
            print("Error converting UIImage to CKAsset!")
        }

        return nil
    }
}

您可以像在问题中一样使用它:
if let asset = ImageToSave.toCKAsset() {
    newRecord.setObject(asset, forKey: "Image")

    CKContainer.defaultContainer().publicCloudDatabase.saveRecord(newRecord, completionHandler: {
      record, error in
      if error != nil {
        println("\(error)")
      } else {
        // saved successfully!
      }
    })
}

1
太棒了!谢谢 KBog!! - Chazman

0

这个答案适用于Swift 2.2和iOS 9,并将文件创建与上传分开,以便您可以针对它们进行正确的测试,因为它们是具有自己潜在问题的不同操作。

对于uploadPhoto函数,recordType变量是您在CloudKit仪表板中使用的值。在photo["photo"] = asset行中,“photo”键是记录类型的字段名称。

func uploadPhoto(image: UIImage, recordName: String) {
    let privateDB = CKContainer.defaultContainer().privateCloudDatabase
    let photoID = CKRecordID(recordName: recordName)
    let photo = CKRecord(recordType: recordType, recordID: photoID)
    let asset = CKAsset(fileURL: writeImage(image))
    photo["photo"] = asset

    privateDB.saveRecord(photo) { (record, error) in
        guard error == nil else {
            print(error?.localizedDescription)

            return
        }
        print("Successful")
    }
}

func writeImage(image: UIImage) -> NSURL {
    let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
    let fileURL = documentsURL.URLByAppendingPathComponent(NSUUID().UUIDString + ".png")
    if let imageData = UIImagePNGRepresentation(image) {
        imageData.writeToURL(fileURL, atomically: false)
    }

    return fileURL
}

您可以使用以下方式调用此函数:
uploadPhoto(UIImage(named: "foo.png")!, recordName: "bar")

-2

您需要在仪表板中选择资产值类型来设置此值。

newRecord.setValue(ImageToSave, forKey: "Image")

CKRecord 不支持 UIImage 类型。最好的选择是将此图像写入文件,然后创建一个 CKAsset 并将其设置到记录中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接