使用 CKAsset 在 CloudKit 中创建了记录,但获取时资产始终为 nil,其他属性正常

Created record in CloudKit with CKAsset but the asset is always nil when fetching, other attributes are ok

我使用 CloudKit 仪表板在 CloudKit 中创建了一条记录。该记录还包含照片的属性,我在保存记录之前上传了该照片。 照片数据存储在 CKAsset 类型的属性中。 在实体核心数据日期模型中,它表示为 Data.

类型的属性

当我稍后在我的本地 sqlLite 数据库上执行 NSFetchRequest 时,它与 CloudKit 应该同步的属性保持图像的二进制数据始终为零。 所有其他属性 - 只是字符串 - 都填充了有效数据。当我更改这些属性并再次执行 NSFetchRequest 时,更改会反映在获取结果中。

我不知道为什么 photo 属性总是 nil 而其他字符串属性包含当前有效值。

编辑 - 提供示例代码。

这是从由 CloudKit 支持的本地 sqlite 数据库获取它的代码,其中照片属性是 nil 即使它在 CloudKit:

        let bgContext = self.newBackgroundContext()
        bgContext.perform {
            do {
                fetchRequest.propertiesToFetch = ["title", "categoryValue", "date", "photo", "amount"]
                let results = try fetchRequest.execute() as! [ReceiptEntity]
                for record in results {
                    let title = record.title
                    let photo = record.photo
                    if let photo_local = photo {
                        log.info("| Photo attribute is present!!")
                    }
                }
               }
            } catch let error {
                let result: Result<[ReceiptEntity], Error> = .failure(error)
                cb(result)
            }

这是实体定义,由Xcode生成:

扩展 ReceiptEntity {

@nonobjc public class func fetchRequest() -> NSFetchRequest<ReceiptEntity> {
    return NSFetchRequest<ReceiptEntity>(entityName: "ReceiptEntity")
}

@NSManaged public var additionalInformation: String?
@NSManaged public var amount: Double
@NSManaged public var categoryValue: String?
@NSManaged public var currencyValue: String?
@NSManaged public var date: Date?
@NSManaged public var placeMark: String?
@NSManaged public var title: String?
@NSManaged public var photo: Data?

}

如前所述:当我直接使用以下代码从 CloudKit 获取某条记录时 - 照片属性有一个 CKAsset 实例并且照片在那里:

    privateDB.fetch(withRecordID: configRecordId) { (record, error) -> Void in
        let photo = record?.value(forKey: "CD_photo") as? CKAsset
        let title = record?.value(forKey: "CD_title") as? String
        
        if let url = photo?.fileURL {
            log.info("| Asset URL: \(url)")
        }

    }

终于找到问题了。 在扩展我的数据模型的迭代过程中,我使用 CK 仪表板在 CloudKit 中手动添加了属性,并将这些属性添加到我的数据模型中。

通过向名为 CD_photo 的 CK 添加 CKAsset 属性。但这是错误的。照片属性的类型应该是“Bytes”,然后是另一个名为 CD_photo_ckAsset 的 CKAsset 类型的属性。

但最简单的方法是让 NSPersistentCloudKitContainer 通过为您创建应用程序的架构。