我正在使用CloudKit构建iOS应用程序.
它应该允许用户Products在云中添加,编辑和删除.用户可以在文件夹中组织这些内容.这些文件夹只是cloudkit中的其他记录类型.用户可以使用的文件夹级别没有限制,因为任何文件夹都可以只保存CKReference到其父文件夹.我的应用程序中的所有CloudKit通信都在专用的CloudKitController类中进行
这一切都有效,但一段时间后停止工作没有明确的理由.
当我测试我的应用程序时,我甚至不会使用多级别的文件夹.但是,使用它一段时间(最多一周)后,所有已删除的记录似乎都会重新出现在CloudKit上.关于这个的几点说明:
它已经有一段时间了,我已经检查过我的代码,Apple Library和Google多次,但我无法弄清楚导致这个问题的原因.
问题: 有人知道如何克服这个问题吗?就像我说的那样,我已经遇到了几个星期,重置我的CloudKit仪表板只能"治愈"它长达一个星期,然后它再次弹出.我也非常乐意发布任何代码,如果这有助于你回答我的问题.我最初没有发布任何代码,因为我不知道代码可能会导致什么.
任何答案都将受到高度赞赏
新的Cloud Kit框架广泛使用NSOperation进行CRUD.这些操作的结果以块为单位返回.例如:
let fetchOperation = CKFetchRecordsOperation(recordIDs: [recordID1, recordId2])
fetchOperation.fetchRecordsCompletionBlock = {(dict: NSDictionary!, error: NSError!) -> Void in
// dict contains RecordId -> Record
// do something with the records here (if no error)
}
Run Code Online (Sandbox Code Playgroud)
我想链接其中的一些操作(依赖项),并将操作的结果传递给链中的下一个操作.简化示例来说明这一点(伪代码!):
let fetchOperation1 = CKFetchRecordsOperation(recordIDs: [recordID1, recordId2])
fetchOperation1.fetchRecordsCompletionBlock = {(dict: NSDictionary!, error: NSError!) -> Void in
if error {
// handle error
} else {
// dict contains RecordId -> Record
// let's pretend our records contain references to other records
// that we want to …Run Code Online (Sandbox Code Playgroud) 我正在尝试将记录保存到CloudKit但是收到错误.我曾在其他地方看到这是一个需要知道如何保存的问题,但我无法让它发挥作用.
var database:CKDatabase = CKContainer.defaultContainer().publicCloudDatabase
var aRecord:CKRecord!
if self.cloudId == nil {
var recordId:CKRecordID = CKRecordID(recordName: "RecordId")
self.cloudId = recordId // Setup at top
}
aRecord = CKRecord(recordType: "RecordType", recordID: self.cloudId)
aRecord.setObject(self.localId, forKey: "localId")
// Set the normal names etc
aRecord.setObject(self.name, forKey: "name")
var ops:CKModifyRecordsOperation = CKModifyRecordsOperation()
ops.savePolicy = CKRecordSavePolicy.IfServerRecordUnchanged
database.addOperation(ops)
database.saveRecord(aRecord, completionHandler: { (record, error) in
if error != nil {
println("There was an error \(error.description)!")
} else {
var theRecord:CKRecord = record as CKRecord
self.cloudId = theRecord.recordID
} …Run Code Online (Sandbox Code Playgroud) 我目前在我的应用程序中设置了CloudKit,以便我使用以下代码的帮助添加新记录,
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:@"stringArray"];
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Strings" recordID:recordID];
[record setObject:[NSArray arrayWithObjects:@"one", @"two", @"three", @"four", nil] forKey:@"stringArray"];
[_privateDatabase saveRecord:record completionHandler:nil];
Run Code Online (Sandbox Code Playgroud)
但是,现在我希望能够获取具有相同记录类型的所有记录"Strings",并将这些记录返回到NSArray中.我该怎么做呢?目前,我所知道的是如何使用recordID单独获取每条记录,这是一个麻烦,必须有一个更简单的方法.
[_privateDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// Error handling for failed fetch from private database
}
else {
NSLog(@"ICLOUD TEST: %@", [record objectForKey:@"stringArray"]);
}
}];
Run Code Online (Sandbox Code Playgroud) 对Cloudkit私有默认区域的查询结果是否有任何限制?我不知道为什么我只使用以下查询收到前100条记录:
let p = NSPredicate(format: "(type == 'entered') AND (timestamp >= %@) AND (timestamp <= %@)", from, to)
let q = CKQuery(recordType: self.beaconRecordType, predicate: p)
q.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
self.privateDatabase?.performQuery(q, inZoneWithID: nil, completionHandler: { results, error in
//count = 100
println(results.count)
}
Run Code Online (Sandbox Code Playgroud)
好的.正如Edwin在答案中提到的,解决方案是使用CKQueryOperation获取初始数据块,然后使用completionBlock中的"cursor"来触发另一个操作.这是一个例子:
UPDATE
func fetchBeacons(from:NSDate, to:NSDate) {
let p = NSPredicate(value: true)
let q = CKQuery(recordType: self.beaconRecordType, predicate: p)
let queryOperation = CKQueryOperation(query: q)
queryOperation.recordFetchedBlock = fetchedARecord
queryOperation.queryCompletionBlock = { [weak self] (cursor : CKQueryCursor!, …Run Code Online (Sandbox Code Playgroud) 我得到致命的错误:"无法在" if (NSKeyedUnarchiver.unarchiveObject(with: loadedData as! Data) as? CKRecord) != nil" 行上将'NSTaggedPointerString'类型的值转换为'NSData' ".
还有另一个致命错误:"当我尝试将locationRecord保存为默认值时,尝试将非属性列表对象设置为键locationData的NSUserDefaults/CFPreferences值".
var locationRecord = CKRecord(recordType: "location")
func getRecordToUpdate(_ locations:CLLocation)
{
if defaults1.object(forKey: "locationData") == nil{
locationRecord.setObject(locations, forKey: "location")
defaults1.set(locationRecord, forKey: "locationData")
self.updateLocationRecord(locations: locations)
}else{
if let loadedData = defaults1.object(forKey: "locationData") {
print("continue")
if (NSKeyedUnarchiver.unarchiveObject(with: loadedData as! Data)) != nil
{
let publicDB = CKContainer.default().publicCloudDatabase
publicDB.fetch(withRecordID: locationRecord.recordID,completionHandler: {
(record, error) in
if error == nil
{
publicDB.delete(withRecordID: (record?.recordID)!, completionHandler: {
(record, error) in
if(error == nil){
print("old record …Run Code Online (Sandbox Code Playgroud) 我想设置iCloud同步以CoreData使用CloudKit.
但是,当我加iCloud在Capabilities并启用CloudKit复选框,Use default container如文档描述不会出现:

相反,我得到了这个:
我\xe2\x80\x99m 正在开发一个应用程序,该应用程序使用 iOS 15 中的新共享支持NSPersistentCloudKitContainer。我没有找到一种方法来告诉 Core Data 一个对象或一组对象不再共享。
例如,如果我创建一组对象然后调用share(_:to:completion:),则这些对象将按预期正确共享并移动到新的自定义CKRecordZone。
现在,如果用户停止使用 共享对象UICloudSharingController,则CKShareCore Data 创建的对象会从 CloudKit 中正确删除,但对象仍位于自定义区域中,并且 Core Data 仍具有与这些对象关联的原始对象CKShare。因此,当我致电 时fetchShares(matching:),我仍然得到CKShare,但当然,这不再有效。过去,使用我自己的代码,我\xe2\x80\x99d 使用UISharingControllers delegate 来获取用户停止共享的通知,然后更新我的模型。但似乎没有办法告诉 Core Data 有关更改的信息。
通过将应用程序移至后台然后前台,或停止应用程序并重新启动来强制 Core Data 获取 CloudKit 更改不会导致 Core Data 注意到共享的更改。
\n有谁知道如何告诉 Core Data 这些对象不再共享?
\n我正在使用CloudKit编写Swift应用程序.当设备在CloudKit中修改记录时,我希望在其他设备的本地存储中更新相应的记录,而不显示推送通知.
我需要调用registerUserNotificationSettings的didFinishLaunchingWithOptions(这意味着用户必须接受我的应用程序的通知),即使我不打算显示任何推送通知?
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert, categories: nil))
Run Code Online (Sandbox Code Playgroud) 我试图在CloudKit中存储联系人组,如果我尝试创建一大组记录,CKReferenced到单个组记录,我会收到错误.
该限制似乎约为700左右的记录.
有没有其他人看到类似的结果,或者可以确认限制的存在(或不存在)?我无法在文档中找到任何内容,也无法通过Google找到任何内容.
注意:我已经将我提交的记录拆分为400或更少的批次,因为这似乎是一个硬限制.
cloudkit ×10
ios ×8
swift ×6
icloud ×4
ios8 ×2
ckquery ×1
ckrecord ×1
ckreference ×1
core-data ×1
function ×1
nsoperation ×1
nspredicate ×1