如何使用 swift 使用云套件上传图片?

How to upload images with cloud kit using swift?

如何使用 swift 从 Cloud Kit 上传和加载图像?

我使用什么属性类型?

我使用什么代码?这是我目前使用的代码...

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")

                    }
                }
        })
        }

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

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

UIImage 不是 CKRecord 上允许的类型。您最好的选择是将此图像写入文件,然后创建一个 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")
                }
            }
        })
    }

这里的内容与 Edwin 的回答类似,但更加简洁。我已经测试过了,效果很好。

此示例将 "myImage" UIImageView 保存到 "mySaveRecord" CKRecord 中,只需将这些名称替换为您各自的名称即可。

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!
    }
})

此答案适用于 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")

我在 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!
      }
    })
}