CloudKit:防止重复记录

nic*_*ona 3 objective-c ios icloud cloudkit

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

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

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

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

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

我的问题是:

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

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

har*_*orn 5

答案:

  1. 不,您不能锁定私有数据库
  2. Cloudkit已经实施并假定您的记录ID是唯一的
  3. 您可以将记录ID设置为任意值(在其非区域部分中)。

说明:

关于您的重复问题。如果您是一个创建记录ID的记录(例如,从您提到的外部记录中获取记录),那么在最坏的情况下,如果您有竞争条件,则应该用相同的数据覆盖其中一个记录。对于两个设备同时启动此过程的极端情况,我认为这不是问题。基本上,您的逻辑是先获取现有记录然后进行修改,这对我来说似乎很合理。

码:

//employeeID is a unique ID to identify an employee
let employeeID = "001"

//Remember the recordID needs to be unique within the same database.
//Assuming you have different record types, it is better to prefix the record name with the record type so that it is unique
let recordName = "Employee-\(employeeID)"

//If you are using a custom zone
let customZoneID = CKRecordZoneID(zoneName: "SomeCustomZone", ownerName: CKCurrentUserDefaultName)
let recordIDInCustomZone = CKRecordID(recordName: recordName, zoneID: customZoneID)

//If you are using the default zone
let recordIDInDefaultZone = CKRecordID(recordName: recordName)
Run Code Online (Sandbox Code Playgroud)