CloudKit 私有数据库返回前 100 个 CKRecords

Posted

技术标签:

【中文标题】CloudKit 私有数据库返回前 100 个 CKRecords【英文标题】:CloudKit private database returns first 100 CKRecords 【发布时间】:2016-04-09 20:09:45 【问题描述】:

我在使用 CloudKit 时遇到了这种问题。试图从“数据”记录中获取所有数据。结果限制为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 
            
        
    

附:我发现了一个类似的问题,仍然不清楚或答案太旧,不适用于新的 Swift 版本

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

【问题讨论】:

您应该使用CKQueryOperation 而不是performQuery。您拥有更多控制权,可以处理更多记录。 【参考方案1】:

好的,我找到了解决方案。见下文:

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)

【讨论】:

【参考方案2】:

凯文,

您使用 CKQueryOperation 返回的游标;它在数据库领域是一种非常标准的方法;例如,我知道一些 Dropbox 操作使用相同的方法。这是 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)

【讨论】:

对我来说它看起来并不基本。我只需要读取所有 privateDatabase 记录。无论如何,谢谢你。将尝试实施。

以上是关于CloudKit 私有数据库返回前 100 个 CKRecords的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit 批量获取?

CloudKit 返回太多记录

多个应用程序用户访问 CloudKit 中的私有数据库

CloudKit,NSPredicate在私有容器中返回计数或确定是否存在任何记录?

限制 CloudKit 中返回的结果数量

Apple CloudKit 分页