CloudKit:获取具有某种记录类型的所有记录?

问题描述:

我当前已得到CloudKit设立在我的应用程序,这样我加入使用下面的下面的代码的帮助的新纪录,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]; 

不过,现在我想能够将所有取记录类型相同的记录“字符串”,并将编译的结果返回给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"]);    
    } 
}]; 
+0

根据CKQuery API参考:“谓词是基于在一个格式字符串上,你不能使用值或基于块的谓词。“我不认为它总是这样,但目前没有答案是正确的,因为他们使用'NSPredicate(value:)' – 2017-05-29 22:48:26

+0

@JamesLingo你试过了吗?这是一个假设吗? “NSPredicate(value:true)'完全没问题 – 2018-01-27 21:30:13

+0

我以前用过它,但根据Apple自己的文档,任何人都应该知道它不支持CloudKit。苹果公司可能会做出改变来破坏代码,并且可以使用基于值或块的谓词来完成。 – 2018-01-29 19:08:44

Aaaand,我明白了。使用下面的代码,我能够创建一个查询在数据库上运行,然后在完成块中返回一个NSArray,并且返回NSLog中保存的键的值。

NSPredicate *predicate = [NSPredicate predicateWithValue:YES]; 
CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Strings" predicate:predicate]; 

[_privateDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) { 
    for (CKRecord *record in results) { 
     NSLog(@"Contents: %@", [record objectForKey:@"stringArray"]); 
    } 
}]; 
+1

这不会返回所有记录,只是一个子集(通常默认限制为100) – 2016-01-03 19:52:09

+0

@MaxDesiatov你的意思是有限的?如何获取所有? – Ryde 2016-01-03 22:27:02

+0

没关系,它(100限制)在这里回答:[link](http://stackoverflow.com/questions/29592964/ckquery-from-private-zone-returns-only-first-100-ckrecords-from-in -cloudkit)和[链接](http://stackoverflow.com/questions/27728115/limit-the-amount-of-results-returned-in-cloudkit) – Ryde 2016-01-03 22:37:29

的followig函数将返回所有记录的请求记录类型:

let database = CKContainer(identifier: "container_here").privateCloudDatabase 
typealias RecordsErrorHandler = ([CKRecord], Swift.Error?) -> Void 

func fetchRecords(forType type: String, completion: RecordsErrorHandler? = nil) { 

    var records = [CKRecord]() 

    let query = CKQuery(recordType: type, predicate: NSPredicate(value: true)) 
    let queryOperation = CKQueryOperation(query: query) 
    queryOperation.zoneID = CloudAssistant.shared.zone.zoneID 

    queryOperation.recordFetchedBlock = { record in 
     records.append(record) 
    } 

    queryOperation.queryCompletionBlock = { cursor, error in 

     self.fetchRecords(with: cursor, error: error, records: records) { records in 
      completion?(records, nil) 
     } 
    } 

    database.add(queryOperation) 
} 

private func fetchRecords(with cursor: CKQueryCursor?, error: Swift.Error?, records: [CKRecord], completion: RecordsHandler?) { 

    var currentRecords = records 

    if let cursor = cursor, error == nil { 

     let queryOperation = CKQueryOperation(cursor: cursor) 

     queryOperation.recordFetchedBlock = { record in 
      currentRecords.append(record) 
     } 

     queryOperation.queryCompletionBlock = { cursor, error in 
      self.fetchRecords(with: cursor, error: error, records: currentRecords, completion: completion) 
     } 

     database.add(queryOperation) 

    } else { 
     completion?(records) 
    } 
} 

下面是雨燕3.0的答案。

func myQuery() { 
    let predicate = NSPredicate(value: true) 
    let query = CKQuery(recordType: "tableName", predicate: predicate) 

    publicDatabase.perform(query, inZoneWith: nil) { (record, error) in 

     for record: CKRecord in record! { 
      //... 

      // if you want to access a certain 'field'. 
      let name = record.value(forKeyPath: "Name") as! String     
     } 
    } 
} 

解决方案斯威夫特4, 展示了如何获取类型 “YourTable” 的所有记录,也打印System FieldCustom Field

let query = CKQuery(recordType: "YourTable", predicate: NSPredicate(value: true)) 
CKContainer.default().publicCloudDatabase.perform(query, inZoneWith: nil) { (records, error) in 
    records?.forEach({ (record) in 

    // System Field from property 
    let recordName_fromProperty = record.recordID.recordName 
    print("System Field, recordName: \(recordName_fromProperty)") 

    // Custom Field from key path (eg: deeplink) 
    let deeplink = record.value(forKey: "deeplink") 
    print("Custom Field, deeplink: \(deeplink ?? "")") 
    }) 
}