【问题标题】:CloudKit private database returns first 100 CKRecordsCloudKit 私有数据库返回前 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。您拥有更多控制权,可以处理更多记录。

标签: ios swift cloudkit


【解决方案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 记录。无论如何,谢谢你。将尝试实施。
    猜你喜欢
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多