2015-02-09 165 views
10

我當前已得到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

回答

8

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

0

的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) 
    } 
} 
2

下面是雨燕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     
     } 
    } 
} 
0

解決方案斯威夫特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 ?? "")") 
    }) 
}