标签: cloudkit

CloudKit:防止重复记录

我正在通过一个将外部Web服务中的数据提取到私有CloudKit数据库中的应用程序进行工作。该应用程序是单用户应用程序,但是我遇到了无法确定如何避免的竞赛情况。

外部数据中的每个记录都有一个唯一的标识符,该标识符映射到CKRecord实例。一般应用启动流程为:

  1. 获取相关记录类型的当前CKRecords。
  2. 提取外部记录。
  3. 对于每个外部记录,如果CloudKit中不存在该记录,则通过批处理创建(修改操作)。

现在的问题是,如果同时在用户的两个设备上启动此过程,则由于CK和外部提取都是异步的,因此很可能会得到重复的记录。

我知道我可以使用区域原子地提交所有CKRecord实例,但是我认为这不能解决我的问题,因为如果所有这些提取都在同一时间发生,那么保存并不是真正的问题。

我的问题是:

  1. 有谁知道一种“锁定”私有数据库以便在所有用户设备上进行写入的方法?
  2. 或者,是否可以在任何CKRecord字段上强制执行唯一性?
  3. 或者,是否可以使用自定义值作为主键,在这种情况下,我可以使用外部ID作为CK ID,并允许系统防止重复本身。

我在这里先向您的帮助表示感谢!

objective-c ios icloud cloudkit

3
推荐指数
1
解决办法
1858
查看次数

3
推荐指数
1
解决办法
539
查看次数

似乎无法在CloudKit中删除订阅?`-deleteSubscriptionWithID`总是返回true

我希望有一位经验丰富的CloudKit大师,但根据我的谷歌搜索查询,我不确定你是否存在.我认为这可能是Apple的一个错误,但我无法确定:

我可以保存订阅我的CKDatabase罚款,没有任何问题.

[publicDatabase saveSubscription:subscription completionHandler:^(CKSubscription *subscription, NSError *error) {
    if (error)
    {
        //No big deal, don't do anything.
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setObject:[subscription subscriptionID] forKey:@"SUBSCRIPTION"];
    }
}];
Run Code Online (Sandbox Code Playgroud)

每当我更改记录中的字段时,我都会收到推送通知,一切都很愉快.

我的问题是删除此订阅.

我试过调用 正如你在上面的代码片段中看到的那样,我保存了订阅ID(还通过调用确认它是正确的订阅ID)-deleteSubscriptionWithID:completionHandler:
-fetchAllSubscriptionsWithCompletionHandler:

我在那条消息中传递了subscriptionID,如下所示:

[publicDatabase deleteSubscriptionWithID:[[NSUserDefaults standardUserDefaults] objectForKey:@"SUBSCRIPTION"] completionHandler:^(NSString * _Nullable subscriptionID, NSError * _Nullable error) {
    if( error ) {
        NSLog(@"ERROR: %@", [error description] );
    }
    else
    {
        NSLog(@"SUCCESS: %@", subscriptionID);
    }
}];
Run Code Online (Sandbox Code Playgroud)

但它不会删除我的订阅: 在此输入图像描述

无论我作为subscriptionID传递什么,都没有错误,我在"删除"时看到"SUCCESS".

在此输入图像描述 在此输入图像描述

...是的.显然这是行不通的.

如果我通过Cloudkit Dashboard手动删除订阅,我的-fetch调用会正确地注意到并返回一个空数组: 在此输入图像描述

所以在这一点上,我确定我要么在代码中错误地删除订阅,要么它已经坏了,并且(不太可能)没有人在SO或任何其他论坛上找到我能找到的?

我也试过用 CKModifySubscriptionsOperation

   CKModifySubscriptionsOperation *deleteSub = …
Run Code Online (Sandbox Code Playgroud)

apple-push-notifications ios cloudkit

3
推荐指数
1
解决办法
975
查看次数

iOS-Swift:CloudKit中的OrPredicate导致无效

我有这一点来检索两个用户之间的所有消息:

let user1 = "john"
let user2 = "mark"
let predicateUser1To2 = NSPredicate(format: "user1 == %@", user1)
let predicateUser2From1 = NSPredicate(format: "user2 == %@", user2)

let predicateUser2To1 = NSPredicate(format: "user2 == %@", user1)
let predicateUser1From2 = NSPredicate(format: "user1 == %@", user2)

let predicate1To2 = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateUser1To2, predicateUser2From1])
let predicate2To1 = NSCompoundPredicate(andPredicateWithSubpredicates: [predicateUser1From2, predicateUser2To1])
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1To2, predicate2To1])

let query = CKQuery(recordType: "Chat", predicate: predicate)
Run Code Online (Sandbox Code Playgroud)

但这会引发以下错误。看来它得到正确的评估,为什么会出错!?

***由于未捕获的异常'CKException'而终止应用程序,原因:'无效谓词:(user1 ==“ john” AND user2 ==“ mark”)OR(user1 ==“ mark” AND user2 ==“ john”) …

nspredicate ios swift cloudkit

3
推荐指数
1
解决办法
381
查看次数

如何知道CloudKit区域是否已存在

要在私有CKRecordZone中添加CKRecord,您需要确保该区域已存在.

但这是否意味着每次我需要插入记录时我需要获取所有区域并查找我的区域是否存在使用fetchAllRecordZonesWithCompletionHandler?效率不高.

采用的最佳策略是什么?

我见过的大多数示例都展示了如何创建区域并在其中添加记录.但是你不是每次都要创建这个区域,你不能只假设它存在......

如果尚未创建区域,则以下代码将失败

let customZone = CKRecordZone(zoneName: self.zoneName!)
// Create a CKRecord
let lessonRecord = CKRecord(recordType: self.recordType, zoneID: customZone.zoneID)
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

zone cloudkit

3
推荐指数
1
解决办法
1070
查看次数

CloudKit中私有存储的数据是否存储在用户的iCloud帐户中?

我的应用程序涉及用户创建数据并将其保存到其私有数据库.数据会占用iCloud帐户中的空间,还是会成为我的CloudKit存储配额的一部分?谢谢!

storage private ios icloud cloudkit

3
推荐指数
1
解决办法
488
查看次数

处理CloudKit错误

我正在寻找有关在Swift中处理CloudKit错误的一般建议,并且无法在线查找好的示例.以下是我想知道的事情:

1)每次出现错误的可能性时,我是否应该考虑每种错误类型,或者这是不是真的有必要?

2)我已经读过处理CloudKit错误的一种常见方法是在错误消息提供的时间间隔之后重试执行操作.这种重试基本上应该是我所有错误的标准程序吗?

3)不同的CloudKit操作(保存,获取等)是否会产生不同类型的错误,或者是否存在一组标准的CloudKit错误?

提前致谢!我只是在寻找有关如何使用CloudKit处理错误处理的一般信息,因为我不确定从哪里开始.

error-handling ios swift cloudkit

3
推荐指数
2
解决办法
1783
查看次数

CloudKit的“原子增量”

我想使用CloudKit实现一个计数器。假设我有一个名为counttype 的字段Int(64)。我该如何实现此计数器,以便多个用户可以同时增加它?

如果多个用户同时增加此计数器,则CKModifyRecordsOperation由于冲突我可能会失败。我可能会失败,然后递归尝试保存记录,但这种方法无法大规模使用。

在2011年,Parse推出了一个称为原子增量的简单解决方案。您可以编写这样的代码,而不必担心多个用户创建相互冲突的值:[gameScore incrementKey:@"score" byAmount:[NSNumber numberWithInt:10]。(这里的帖子)

如何使用CloudKit做到这一点?

ios swift cloudkit

3
推荐指数
1
解决办法
192
查看次数

cloudkit错误未收到资产的authToken

为什么在运行以下代码时出现此错误?:

“内部错误”(1/1000);“未收到资产的authToken”

我认为这与setObject最后一行中的代码有关。

let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
var imageURL: URL!

let imageData = UIImageJPEGRepresentation(self.newImage, 1.0)
let path:String = documentsDirectoryPath.appendingPathComponent(self.newImage.description)
try? UIImageJPEGRepresentation(self.newImage, 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomicWrite])
imageURL = URL(fileURLWithPath: path)
try? imageData?.write(to: imageURL, options: [.atomicWrite])

let imageAsset:CKAsset? = CKAsset(fileURL: URL(fileURLWithPath: path))


curImages = record["Images"] as! [CKAsset]
curImages.append(imageAsset!)

print("saving image")
record.setObject(curImages as CKRecordValue?, forKey: "Images")
Run Code Online (Sandbox Code Playgroud)

ios swift cloudkit

3
推荐指数
1
解决办法
264
查看次数

核心数据和CloudKit同步WWWDC 2019不适用于Beta 3

我正在尝试复制有关自动将核心数据与云工具包同步的WWDC讨论的结果。

我尝试了三种方法:

  1. 制作一个新的主从视图应用程序并按照wwdc 2019演讲中的步骤进行操作,在这种情况下不会发生同步

  2. 在这种情况下,也将下载示例wwdc 2019应用程序

  3. 我制作了一个带有少量核心数据和云工具包容器的小型应用程序,在这种情况下,发生了同步,但是我必须重新启动该应用程序。我怀疑这与历史记录管理有关,因此观察到NSPersistentStoreRemoteChange通知并非一无所获。

感谢任何帮助。

synchronization core-data cloudkit

3
推荐指数
2
解决办法
417
查看次数