Сохранение списка активов (массива) в конкретный CKRecord
У меня есть тип CKRecord, созданный в бэкэнде CloudKit с некоторыми свойствами, связанными с этим классом.
У меня есть свойства String, у байтов и у меня есть свойство Asset List, поэтому храните некоторые изображения (несколько изображений, связанных с одной записью).
Теперь я пытаюсь сохранить некоторые изображения, а затем заполнить свойство, а затем пытаюсь сохранить его в CloudKit, но это не работает.
Код выглядит следующим образом:
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) }
}
Если я только сохраняю строки, все работает отлично, но с изображениями это не сохраняет запись.
Я знаю, что могут быть какие-то проблемы с добавлением, или я должен сохранить массив другим способом, или я не должен сохранять его как CKRecordValue.
Есть ли у вас какие-либо советы о том, как этого добиться?
Спасибо
2 ответа
Когда вы создаете свой локальный файл ресурсов, вы должны сделать это с опцией атомарной записи. Это обеспечит полную запись файла перед тем, как CloudKit попытается загрузить ресурс.
Это функция создания файла актива, которую я использую в библиотеке Seam 3:
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
}
Вы должны взять массив CKAsset
для изображений.
var imageUrls = [CKAsset]()
Теперь получите все изображения, используя цикл for. И сохраните CKAsset изображений.
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)
}
Установите свой массив.
record.setObject(imageUrls, forKey: "images_array")