iOS,如何处理iCloudKit交易的发布通知请求?

时间:2017-02-26 22:29:49

标签: ios cocoa-touch icloud icloud-api

首先,如果用户拒绝接受推送通知的请求,该怎么做呢?

从我所看到的情况来看,似乎静音通知存在问题,虽然我认为它是测试版,但此问题已得到纠正。

我正在开发儿童应用,当我致电registerForRemoteNotifications来捕获无声通知时,会显示通知权限消息。

我还想知道如果用户不经常访问互联网,iCloud数据库设置会发生什么。我的意思是我猜他们必须在第一次下载应用程序时拥有它,但如果它们在下载之后从未运行过该应用程序,他们将如何获取数据库模式?这是我们必须处理并要求用户连接到互联网吗?

我知道很多这是假设的,但显然我们需要捕获并处理这个问题。

如果有人能指出可能有帮助的有用豆荚,我也将不胜感激。

1 个答案:

答案 0 :(得分:1)

朱,

使用支持iCloud的应用程序创建记录时,您可以使用与此类似的代码。

func files_saveNotes(rex: Int) {
     var localChanges:[CKRecord] = []

        let newRecordID = CKRecordID(recordName: sharedDataAccess.returnRexID(index2seek: rex))
        let newRecord = CKRecord(recordType: "Blah", recordID: newRecordID)

        let theLinkID = CKReference(recordID: sharedDataAccess.iCloudID, action: .deleteSelf)
        let thePath = sharedDataAccess.fnGet(index2seek: rex)
        newRecord["theLink"] = theLinkID
        newRecord["theBLAHnumber"] = rex as CKRecordValue?
        newRecord["theBLAHpath"] = thePath as CKRecordValue?

    localChanges.append(newRecord)
    let records2Erase:[CKRecordID] = []

    let saveRecordsOperation = CKModifyRecordsOperation(recordsToSave: localChanges, recordIDsToDelete: records2Erase)
    saveRecordsOperation.savePolicy = .allKeys
    saveRecordsOperation.perRecordCompletionBlock =  { record, error in
        if error != nil {
            //print(error!.localizedDescription)
        }
        // deal with conflicts
        // set completionHandler of wrapper operation if it's the case
    }
    saveRecordsOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
        self.theApp.isNetworkActivityIndicatorVisible = false

        guard error == nil else {
            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.files_saveNotes), 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.files_saveNotes), 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.files_saveNotes), userInfo: nil, repeats: false)
                    }
                } else if ckerror.code == CKError.notAuthenticated {
                    NotificationCenter.default.post(name: Notification.Name("noCloud"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.networkFailure {
                    NotificationCenter.default.post(name: Notification.Name("networkFailure"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.networkUnavailable {
                    NotificationCenter.default.post(name: Notification.Name("noWiFi"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.quotaExceeded {
                    NotificationCenter.default.post(name: Notification.Name("quotaExceeded"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.partialFailure {
                    NotificationCenter.default.post(name: Notification.Name("partialFailure"), object: nil, userInfo: nil)
                } else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable) {
                    NotificationCenter.default.post(name: Notification.Name("serviceUnavailable"), object: nil, userInfo: nil)
                }
            } // end of guard statement
            return
        }
        if error != nil {
            print(error!.localizedDescription)
        } else {
            print("ok \(savedRecords)")
        }
    }

    saveRecordsOperation.qualityOfService = .background
    privateDB.add(saveRecordsOperation)
    theApp.isNetworkActivityIndicatorVisible = true
}

现在原谅我这里有很多内容,我没有时间详细解释,但记录方案来自CKRecord创建调用此代码中的第4行,记录类型称为& #34;布拉赫"在这种情况下。

其中的字段[架构],您需要在我的代码中详细说明代码,因此在这种情况下我们有link,BLAHnumber和BLAHpath。它不会下载此信息,实际上一旦投入生产,您就无法更改它。所以新的模式需要是新的记录类型,你需要注意现有的更新,以确保你的应用程序是向后的。兼容。希望有助于使事情更清晰。

本文https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit详细讨论了整个主题。原子提交,特别提到你的一个问题。