将资产列表(数组)保存到特定的CKRecord [英] Saving an Asset List (array) to specific CKRecord

查看:139
本文介绍了将资产列表(数组)保存到特定的CKRecord的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在CloudKit后端中创建了一个CKRecord类型,其中包含与该类相关的一些属性.

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

现在,我正在尝试存储一些图像,然后填充该属性,然后尝试将其保存到CloudKit,但这是行不通的.

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.

代码如下:

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.

我知道附加可能存在任何问题,或者我不得不以其他方式保存数组,或者我不应该将其另存为CKRecordValue.

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?

谢谢

推荐答案

创建本地资产文件时,应使用原子写入"选项.这样可以确保在CloudKit尝试上传资产之前,文件已完全写入.

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.

这是我在 Seam 3 库中使用的资产文件创建功能:

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

}

这篇关于将资产列表(数组)保存到特定的CKRecord的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆