Saving an Asset List (array) to specific CKRecord

本秂侑毒 提交于 2019-12-22 17:04:08

问题


I've a CKRecord type created in the CloudKit backend with some properties related to that class.

I've String properties, Bytes and I have a Asset List property, so store some images (multiple images related to a single record).

Now I'm trying so store some images and then fill the property and then trying to save it to CloudKit, but it's not working.

Code goes as it follows:

var images_array = [CKAsset]()

// append the an image to the array 
images_array.append(CKAsset(fileURL: writeImage(image: selectedImage) as URL))


let record = CKRecord(recordType: recordName)
record["class_title"] = someString as CKRecordValue
record["class_body"]  = someString as CKRecordValue
record["images_array"] = images_array as CKRecordValue
saveRecord(record)

func saveRecord(_ xrecord: CKRecord) {
    let publicData = CKContainer.default().publicCloudDatabase
    let record: [CKRecord] = [xrecord] 
    let saveOperation = CKModifyRecordsOperation.init(recordsToSave: record, recordIDsToDelete: nil)

    saveOperation.perRecordCompletionBlock = {(record, error) -> Void in
        if (error != nil) {
            print("error")
        }
    }
    publicData.add(saveOperation)
}


func writeImage(image: UIImage) -> URL {
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let fileURL = NSURL(fileURLWithPath: documentsURL.absoluteString).appendingPathComponent(".jpg")

    if let imageData = image.lowestQualityJPEGNSData {
        do {
            try imageData.write(to: fileURL!)
        } catch {
            print("ERRO 001 = \(error.localizedDescription)")
        }
    }
    return fileURL!
}

extension UIImage {
    var uncompressedPNGData: Data?      { return UIImagePNGRepresentation(self)        }
    var highestQualityJPEGNSData: Data? { return UIImageJPEGRepresentation(self, 1.0)  }
    var highQualityJPEGNSData: Data?    { return UIImageJPEGRepresentation(self, 0.75) }
    var mediumQualityJPEGNSData: Data?  { return UIImageJPEGRepresentation(self, 0.5)  }
    var lowQualityJPEGNSData: Data?     { return UIImageJPEGRepresentation(self, 0.25) }
    var lowestQualityJPEGNSData:Data?   { return UIImageJPEGRepresentation(self, 0.0)  }
}

If I only save the strings, everything works perfectly but with images it doesn't save the record.

I know there might be any issue with the appending, or I have to save the array in other way, or I shouldn't save it as CKRecordValue.

Do you have any tip on how to achieve this?

Thanks


回答1:


When you create your local asset file you should do so with the atomic write option. This will ensure that the file is completely written before CloudKit attempts to upload the asset.

This is the asset file creation function I use in the Seam 3 library:

fileprivate func createAsset(data: Data) -> CKAsset? {

    var returnAsset: CKAsset? = nil

    let tempStr = ProcessInfo.processInfo.globallyUniqueString
    let filename = "\(tempStr)_file.bin"        
    let baseURL = URL(fileURLWithPath: NSTemporaryDirectory())       
    let fileURL = baseURL.appendingPathComponent(filename, isDirectory: false)

    do {
        try data.write(to: fileURL, options: [.atomicWrite])         
        returnAsset = CKAsset(fileURL: fileURL)      
    } catch {
        print("Error creating asset: \(error)")
    }

    return returnAsset

}



回答2:


You have to take Array of CKAsset for images.

var imageUrls = [CKAsset]()

Now get all images using for-loop. And save CKAsset of images.

for images in self.arrayImageSelected{

                  var myImage = UIImage()
                  if (images.isKindOfClass(PHAsset)){
                        let imageC = images as? PHAsset
                        myImage = self.getAssetThumbnail(imageC!)
                    }else if (images.isKindOfClass(UIImage)){
                        myImage = (images as? UIImage)!
                    }
                    let imagePath = self.storeImageAtDocumentDirectory(myImage, titleName: self.strTitle)
                    myPAth.append(imagePath)
                    let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
                    let FbPath = paths.stringByAppendingString("/Custom")
                    let filePathToWrite = "\(FbPath)" + imagePath
                    let urls = NSURL(fileURLWithPath: filePathToWrite)
                    let imageAsset = CKAsset(fileURL: urls)
                    imageUrls.append(imageAsset)

                }

Set Your array.

record.setObject(imageUrls, forKey: "images_array")


来源:https://stackoverflow.com/questions/43357769/saving-an-asset-list-array-to-specific-ckrecord

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!