简体   繁体   English

Swift 4 CloudKit queryCompletionBlock似乎没有执行

[英]Swift 4 CloudKit queryCompletionBlock doesn't appear to execute

I followed several CKQueryOperation examples/narratives on problems to fetch from CloudKit. 我遵循了几个有关从CloudKit中获取问题的CKQueryOperation示例/说明。 My table has about 370 rows and 8 columns..at best I can only fetch about 60 rows. 我的表有大约370行和8列。.充其量我只能获取大约60行。 resultsLimit parameter does not seem to help.. My queryCompletionBlock is not executing. resultsLimit参数似乎没有帮助。我的queryCompletionBlock没有执行。 Sometimes I fetch 5 rows and other time 30+ Response from Cloud is quick just now all rows It's got to be some newbie code mistake! 有时我获取5行,其他时间获取30+的云,所有行现在的响应很快,这一定是一些新手代码错误!

func getData() {
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: RemoteFunctions.RemoteRecords.booksDB, predicate: predicate)
    let cloudContainer = CKContainer.default()
    let privateDatabase = cloudContainer.privateCloudDatabase
    let operation = CKQueryOperation(query: query)

    operation.queuePriority = .veryHigh
    operation.resultsLimit = 20

    operation.recordFetchedBlock = { (record: CKRecord) in
        self.allRecords.append(record)
         print(record)
    }
    operation.queryCompletionBlock = {[weak self] (cursor: CKQueryCursor?, error: NSError?) in
        // There is another batch of records to be fetched
        print("completion block called with \(String(describing: cursor))")

        if let cursor = cursor  {
            let newOperation = CKQueryOperation(cursor: cursor)
            newOperation.recordFetchedBlock = operation.recordFetchedBlock
            newOperation.queryCompletionBlock = operation.queryCompletionBlock
           newOperation.resultsLimit = 10
            privateDatabase.add(newOperation)
            print("more records")
        }
            // There was an error
        else if let error = error {
            print("Error:", error)
        }

            // No error and no cursor means the operation was successful
        else {
            print("Finished with records:")
        }
        } as? (CKQueryCursor?, Error?) -> Void

// privateDatabase.add(operation) // privateDatabase.add(operation)

}

Remove the as? (CKQueryCursor?, Error?) -> Void 删除as? (CKQueryCursor?, Error?) -> Void as? (CKQueryCursor?, Error?) -> Void near the end. as? (CKQueryCursor?, Error?) -> Void在尽头。 Be careful not to remove the preceeding brace. 注意不要卸下前面的支架。

Remove newOperation.resultsLimit = 10 in your cursor block. 在游标块中删除newOperation.resultsLimit = 10

Add operation = newOperation immediately above privateDatabase.add(newOperation) privateDatabase.add(newOperation)正上方添加operation = newOperation

Uncomment the privateDatabase.add(operation) 取消注释privateDatabase.add(operation)

That should help. 那应该有帮助。 Large fetches, where the cursor block gets hit more than 3 times can be problematic. 较大的访存会导致光标块被命中3次以上的情况。 If you do the above, you should be ok. 如果执行上述操作,应该没问题。 Some people like to write/call the cursor block as its own function. 有些人喜欢将游标块作为其自身的功能来编写/调用。 That works as well, but it isn't necessary. 效果也不错,但这不是必需的。

You could try this... 你可以试试这个...

func getData(withCursor cursor: CKQueryCursor? = nil)
    {
    let cloudContainer = CKContainer.default()
    let privateDatabase = cloudContainer.privateCloudDatabase

    let operation: CKQueryOperation

    if let cursor = cursor
    {
        operation = CKQueryOperation(cursor: cursor)
    }
    else
    {
        let operation_configuration: CKOperationConfiguration = CKOperationConfiguration()
        operation_configuration.isLongLived = true
        operation_configuration.qualityOfService = .background

        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: RemoteFunctions.RemoteRecords.booksDB, predicate: predicate)

        operation = CKQueryOperation(query: query)
        operation.queuePriority = .veryHigh
        operation.configuration = operation_configuration


        operation.recordFetchedBlock = { (record: CKRecord) in
            self.allRecords.append(record)
                print(record)
        }

        operation.queryCompletionBlock = {[weak self] (cursor: CKQueryCursor?, error: NSError?) in
            // There is another batch of records to be fetched
            print("completion block called with \(String(describing: cursor))")

            if let error = error 
            {
                print("Error:", error)
            }
            else if let cursor = cursor  
            {
                self.getData(withCursor: cursor)
            }
            else
            {
                print("Finished with records:")
            }
        }
    }

    privateDatabase.add(operation)
}

This is a recursive version of your fuction, using the new CKQueryOperation API. 使用新的CKQueryOperation API,这是功能的递归版本。

It seems that your're loosing reference to the operation object when a cursor arrives. 似乎当光标到达时,您正在丢失对操作对象的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM