CloudKit:CKRecord 问题(或错误?)的 creatorUserRecordID

Posted

技术标签:

【中文标题】CloudKit:CKRecord 问题(或错误?)的 creatorUserRecordID【英文标题】:CloudKit: creatorUserRecordID of CKRecord Issue (or Bug?) 【发布时间】:2015-04-13 04:16:46 【问题描述】:

ios 8.3以后,如果记录是当前账号创建的,它的creatorUserRecordID会像

CKRecordID: [某个地址]; defaultOwner:(_defaultZone:defaultOwner)

然后如果使用 fetchRecordWithID:completionHandler: 从 CKDatabase 获取这个记录ID,它总是会返回类似的错误

CKError [Some Address]: "Unknown Item" (11/2003); server message = "找不到记录"; uuid = [一些 UUID];容器 ID = [某些容器 ID]

我从来没有遇到过这个问题。

这是一个错误,还是我应该像这样 ( defaultOwner ) 以其他方式从 recordID 获取记录?

编辑(添加示例代码)

- (void)postMoodFeed:(NSString *)moodFeed

    CKRecord *moodRecord = [[CKRecord alloc] initWithRecordType:@"Mood"];
    moodRecord[@"moodFeed"] = moodFeed

    [[[CKContainer defaultContainer] publicCloudDatabase] saveRecord:moodRecord completionHandler:^(CKRecord *record, NSError *error) 
        [self queryMyMood];
    ];


- (void)queryMyMood

    // currentUserRecordID is fetched from fetchUserRecordIDWithCompletionHandler: of CKContainer
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"creatorUserRecordID = %@", currentUserRecordID];

    CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Mood" predicate:predicate];

    [[[CKContainer defaultContainer] publicCloudDatabase] performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) 
        if (results) 
            for (CKRecord *eachRecord in results) 
                // Following logs are all __defaultOwner__
                NSLog(@"%@", eachRecord.creatorUserRecordID.recordName);
                [[[CKContainer defaultContainer] publicCloudDatabase]fetchRecordWithID:eachRecord.creatorUserRecordID completionHandler:^(CKRecord *record, NSError *error) 
                    // All following logs are "Unknown item" error
                    NSLog(@"%@", error);
                ];
            
        
    ];

编辑 2015 年 7 月 2 日

这是一个错误。

在向 Apple 报告后,他们在 iOS 9 Beta 2 中修复了此问题。

【问题讨论】:

以前有用吗?您最近是否在 CloudKit 仪表板中重置了数据库?如果是这样,您是否检查了 User recordType 上的 ID 查询? 1.之前的代码相同(我没有更改任何行。) 2. 是的,我尝试重置数据库(开发环境) 3. 您的意思是查询用户记录类型的 defaultOwner 记录ID?我会试试的。 那么它应该可以工作。您能否向我们展示您如何首先读取记录然后读取 userRecord 的代码?另一件事。不建议将您的应用程序基于 defaultOwner 字段的功能。如果您决定将数据迁移到不同的结构,并使用应用程序来执行此操作,那么所有新记录都将存储在数据库中,并具有执行迁移的进程的 defaultOwner。除此之外,您也不应该使用 User 记录类型,因为它是一种功能有限的特殊记录类型。改为创建您自己的用户记录类型。 如果有用户创建的记录“Feed”,下次我抓取这条Feed记录,我会发现这个Feed的creatorUserRecordID的recordName是defaultOwner。然后获取它,它来了错误。 直到上周末才发生这种情况(我刚刚更新到 iOS 8.3 和 Xcode 6.3)。我发现 creatorUserRecordID 的 recordName 是该用户记录的正确唯一名称,而不是 defaultOwner 之前。 【参考方案1】:

确实,它看起来像是新功能。

您可以做的是首先测试 eachRecord.creatorUserRecordID.recordName == "defaultOwner" 如果是这种情况,您可以获取从 currentUserRecordID 获得的 ID 的记录

但最好不要将 creatorUserRecordID 用于您应用中的任何功能。您最好添加一个新的 CKReference 字段并始终使用 currentUserRecordID 填充它。然后,即使您有一个迁移数据的流程,您仍然会知道最初是谁创建了该记录。

【讨论】:

我同意,有时creatorUserRecordID 的工作方式很奇怪,最好通过CKReference 下载记录而不是creatorUserRecordID,在我的情况下它可能不会下载所有记录 您好 Edwin,您能否给我有关 CKReference 字段的信息。假设我有一个记录类型“Notes”。你说向这个类型添加一个新的 CKReference 文件是更好的选择。好的,应该使用什么 RecordID 创建该参考 - 使用创建者的 RecordID 或者我错了。我应该添加 CKReferenceActionDeleteSelt 吗? @ivan CKReference 将包含一个 RecordID,它定义了关系和一个动作(None 或 DeleteSelf)。因此,例如,订单记录将具有对客户的 CKReference。如果您希望在删除客户端时删除订单,请将其设置为 DeleteSelf。有关更多信息,请参阅developer.apple.com/library/prerelease/ios/documentation/… 啊,你更新了你的问题......是的,我的意思是创建者的recordId。添加 DeleteSelf 取决于您想要的功能。 在您对我的第一条评论中,您指的是有两个记录类型第二个带有指向第一个的引用。我对吗?由于我的第一条记录(注释)包含纬度/经度,我想使用谓词获取我附近 x 半径的记录,无论记录是否属于我,然后评估哪个是我的。因此,我不确定如何组织 CKReference 字段【参考方案2】:

也许这会有所帮助:我发现如果您在应用工作流程的开头使用 [CKFetchRecordsOperation fetchCurrentUserRecordOperation],您将不会有 defaultOwner CKRecordIDs 无处不在。

【讨论】:

向 Apple 报告后,他们在 iOS 9 Beta 2 中修复了这个问题 :)

以上是关于CloudKit:CKRecord 问题(或错误?)的 creatorUserRecordID的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法访问 CloudKit 中 CKRecord 的 createdAt 字段?

快速从 Cloudkit 中删除 CKRecord

如何删除 CKRecord 和 CloudKit 中的所有引用记录

在 Cloudkit 中更改 CKRecord 的 CKRecordID 是不是合法?

CloudKit - 在 CKRecord 中存储多个 CKReference

在 CloudKit 中创建指向多个 CKRecord 的引用列表