CloudKit 私有数据库 returns 前 100 条 CKRecords

CloudKit private database returns first 100 CKRecords

我在使用 CloudKit 时遇到了这种问题。正在尝试从 "Data" 记录中获取所有数据。结果以100为限。如何获取所有数据?请,感谢您的任何建议。

func getAllDataFromCloudKit(){
    let predicate = NSPredicate(value: true)
    let container = CKContainer.defaultContainer()
    let privateDatabase = container.privateCloudDatabase
    let query = CKQuery(recordType: "Data", predicate: predicate)

    privateDatabase.performQuery(query, inZoneWithID: nil) { results, error in
        if error != nil {
            print(error)
        }
        else {
            for result in results! {
                // return only 100 first 
            }
        }
    }
}

P.S。我发现了一个类似的问题,仍然不清楚或者答案太旧并且不适用于新的 Swift 版本

编辑:查看我的最终解决方案如何从下面的私有数据库中获取所有数据:

凯文,

您使用CKQueryOperation返回的游标;它是数据库领域的标准方法;例如,我知道一些保管箱操作使用相同的方法。这是 CKQueryOperation 的基本代码。

func query4Cloud(theLink: String, theCount: Int) {
    var starCount:Int = 0
    let container = CKContainer(identifier: "iCloud.ch")
    let publicDB = container.publicCloudDatabase
    let singleLink2LinkthemALL = CKRecordID(recordName: theLink)
    let recordToMatch = CKReference(recordID: singleLink2LinkthemALL, action: .DeleteSelf)
    let predicate = NSPredicate(format:"theLink == %@", recordToMatch)
    let query = CKQuery(recordType: "Files", predicate: predicate)

    // You run the query operation replacing query with your cursor

    readerOperation = CKQueryOperation(query: query)
    readerOperation.desiredKeys = ["record.recordID.recordName"];

    readerOperation.recordFetchedBlock = { (record) in
        starCount += 1
    }

   // see cursor here, if it is nil than you have no more records
   // if it has a value than you have more records to get

    readerOperation.queryCompletionBlock = {(cursor, error) in
            print("fcuk query4Cloud \(theLink) \(theCount) \(starCount)" )
            if error != nil {
                 self.showAlert(message: error!.localizedDescription)
                print("ting, busted")
            } else {
                // it's done
            }

    }
    print("publicDB.addOperation(operation)")
    readerOperation.qualityOfService = .Background
    publicDB.addOperation(readerOperation)
}

好的,我找到了解决办法。见下文:

func loadDataFromCloudKit() {
    var results: [AnyObject] = []
    let cloudContainer = CKContainer.defaultContainer()
    let privateDatabase = cloudContainer.privateCloudDatabase

    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "Data", predicate: predicate)
    query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]

    let queryOperation = CKQueryOperation(query: query)
    queryOperation.desiredKeys = ["id","name"]
    queryOperation.queuePriority = .VeryHigh
    // Max limit is still 100
    queryOperation.resultsLimit = 100

    queryOperation.recordFetchedBlock = { (record:CKRecord!) -> Void in
        results.append(record)
    }

    queryOperation.queryCompletionBlock = { (cursor, error) in
        dispatch_async(dispatch_get_main_queue()) {
            if (error != nil) {
                print("Failed to get data from iCloud - \(error!.localizedDescription)")
            } else {
                print("Successfully retrieve the data form iCloud")

            }
        }
        // see cursor here, if it is nil than you have no more records
        // if it has a value than you have more records to get
        if cursor != nil {
            print("there is more data to fetch")
            let newOperation = CKQueryOperation(cursor: cursor!)
            newOperation.recordFetchedBlock = { (record:CKRecord!) -> Void in
                results.append(record)
            }

            newOperation.queryCompletionBlock = queryOperation.queryCompletionBlock
            privateDatabase.addOperation(newOperation)
        } else {
            // gets more then 100
            print(results.count)
        }
    }
    privateDatabase.addOperation(queryOperation)
}