iOS,如何处理 post 个 iCloudKit 交易通知请求?
iOS, How to handle post notification request(s) for iCloudKit Transactions?
首先,如果用户拒绝接受推送通知的请求,如何评估。
根据我的阅读,静默通知似乎存在问题,虽然我认为它是测试版,但这个问题是否已得到纠正。
我正在开发一个儿童应用程序,当我调用 registerForRemoteNotifications
来捕获静默通知时,是否会显示通知权限消息。
我还想知道如果用户只是偶尔访问互联网,iCloud 数据库设置会发生什么情况。我的意思是我猜他们必须在首次下载应用程序时拥有,但如果他们在下载应用程序后从未 运行 应用程序,他们将如何获得数据库架构?这是我们必须处理并要求用户连接到互联网的事情吗?
我知道其中很多都是假设,但显然我们需要捕获并处理它。
如果有人能指出有用的信息,我也将不胜感激pods,这可能会有所帮助。
朱尔斯,
当您使用支持 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行,记录类型称为"Blah" 在这种情况下。
其中的字段[架构],您需要像我在这里所做的那样在您的代码中详细说明,因此在这种情况下我们有链接、BLAH 编号和 BLAH 路径。它不会下载此信息,而且一旦投入生产,就无法更改它。因此,新模式需要是新的记录类型,并且您需要注意对当前模式的字段更新,以确保您的应用程序是落后的。兼容的。希望这有助于让事情变得更清楚。
这篇文章 https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit 更详细地讨论了整个主题。原子提交,这里特别提到了你的一个问题。
首先,如果用户拒绝接受推送通知的请求,如何评估。
根据我的阅读,静默通知似乎存在问题,虽然我认为它是测试版,但这个问题是否已得到纠正。
我正在开发一个儿童应用程序,当我调用 registerForRemoteNotifications
来捕获静默通知时,是否会显示通知权限消息。
我还想知道如果用户只是偶尔访问互联网,iCloud 数据库设置会发生什么情况。我的意思是我猜他们必须在首次下载应用程序时拥有,但如果他们在下载应用程序后从未 运行 应用程序,他们将如何获得数据库架构?这是我们必须处理并要求用户连接到互联网的事情吗?
我知道其中很多都是假设,但显然我们需要捕获并处理它。
如果有人能指出有用的信息,我也将不胜感激pods,这可能会有所帮助。
朱尔斯,
当您使用支持 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行,记录类型称为"Blah" 在这种情况下。
其中的字段[架构],您需要像我在这里所做的那样在您的代码中详细说明,因此在这种情况下我们有链接、BLAH 编号和 BLAH 路径。它不会下载此信息,而且一旦投入生产,就无法更改它。因此,新模式需要是新的记录类型,并且您需要注意对当前模式的字段更新,以确保您的应用程序是落后的。兼容的。希望这有助于让事情变得更清楚。
这篇文章 https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit 更详细地讨论了整个主题。原子提交,这里特别提到了你的一个问题。