如果缺少qualityOFService,则不会调用Cloudkit错误处理

时间:2018-10-12 09:55:41

标签: swift cloudkit

我正在尝试处理Cloudkit错误。我读了这篇文章:CloudKit - full and complete error handling example 但是我有几个问题:

1。如果我未设置.qualityOFService,为什么错误处理不起作用?并且.userInitiated是正确的,就像在上面提到的帖子中将其设置为.background?另外,我是否必须将其设置为     loadDataAgain()

2。如何使错误处理可重用,从而产生错误和另一个参数(根据viewcontroller     叫来)?

 @objc func loadData() {
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: myRecordType.type, predicate: predicate)
    query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    let queryOperation = CKQueryOperation(query: query)
    queryOperation.resultsLimit = 5
   //if the below line is missing errors will not be handled
    queryOperation.qualityOfService = .userInitiated
    queryOperation.recordFetchedBlock = { item in
        self.array.append(item)
    }
    queryOperation.queryCompletionBlock = { cursor, error in
        if error != nil{
          if let ckerror = error as? CKError {
            if ckerror.code == CKError.requestRateLimited {
                let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                DispatchQueue.main.async {
                    Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.loadData), userInfo: nil, repeats: false)
                }
            } else if ckerror.code == CKError.zoneBusy {
                let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                DispatchQueue.main.async {
                    Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.loadData), userInfo: nil, repeats: false)
                }
            } else if ckerror.code == CKError.limitExceeded {
                let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                DispatchQueue.main.async {
                    Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.loadData), userInfo: nil, repeats: false)
                }
            } else if ckerror.code == CKError.notAuthenticated {
                //present relevant alert with action to reload ViewController
            } else if ckerror.code == CKError.networkFailure {
                //present relevant alert with action to reload ViewController
            } else if ckerror.code == CKError.networkUnavailable {
                //present relevant alert with action to reload ViewController
            } else if ckerror.code == CKError.quotaExceeded {
                //present relevant alert with action to reload ViewController
            } else if ckerror.code == CKError.partialFailure {
                //present relevant alert with action to reload ViewController
            } else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable) {
                //present relevant alert with action to reload ViewController
            }
        }
        }
        else{
            if cursor != nil {
                self.loadDataAgain(cursor!)
            }
        }
        OperationQueue.main.addOperation {
            self.tableView.reloadData()
        }
}

func loadDataAgain(_ cursor: CKQueryOperation.Cursor) {
    let queryOperation = CKQueryOperation(cursor: cursor)
    queryOperation.resultsLimit = 5

    queryOperation.recordFetchedBlock = { item in
        self.array.append(item)
    }
    queryOperation.queryCompletionBlock = { cursor, error in
        if error != nil{
            //have the same error handling as above
        }
        else{
            if cursor != nil {
                self.loadDataAgain(cursor!)
            }
        }
        OperationQueue.main.addOperation {
            self.tableView.reloadData()
        }
    }
    Database.share.publicDB.add(queryOperation)
}

1 个答案:

答案 0 :(得分:0)

关于您的第一个问题,请参见this answer,该报告建议不因服务质量较低而报告错误:

  

这是因为[the]系统正在等待更好的网络状况,而[if]设置.default.userInitiated时,系统期望“实时”响应

如果您查看the docs的能源效率,苹果似乎肯定了这种方法,

  

CKOperation是NSOperation类的子类。尽管NSOperation类的默认QoS级别为NSQualityOfServiceBackground,但CKOperation对象的默认QoS级别为NSQualityOfServiceUtility。在此级别,当您的应用未使用时,网络请求将被视为可酌情处理的。在iPhone上,启用低功耗模式会暂停任意操作。

如果您不想使用默认的.utility,则需要为创建的每个CKOperation显式设置一个不同的QOS。如果您发现自己经常通过相关操作执行此操作,建议您查看CKOperationGroup及其default configuration property-如果在配置中设置了QOS,它将覆盖所有{{1 }}。