2017-02-26 59 views
0

首先,如果用户拒绝接受推送通知的请求,如何评估呢?iOS,如何处理iCloudKit Transactions的发布通知请求?

从我看过的文章看来,虽然我认为这是一个测试版,但是这个问题已被纠正,似乎有一个无声通知的问题。

我正在开发一个儿童应用程序,当我拨打registerForRemoteNotifications来捕获无声通知时,是否会显示通知许可消息。

我也想知道如果用户只有很少的互联网接入,iCloud数据库设置会发生什么。我的意思是我猜他们必须在应用程序第一次下载时有,但是如果他们在下载完成后从不运行应用程序,他们将如何获得数据库模式?这是我们必须处理的事情,并要求用户连接到互联网?

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

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

+0

啊,我已经回答了我的一个问题,我发现这个错误已经修复http://stackoverflow.com/questions/31108576/cloudkit-push-notifications-on-record-update-stopped-working – Jules

回答

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号线在此代码,记录类型在这种情况下称为“Blah”。

其中[该模式]的领域,你需要在你的代码中详细说明,因为我们在这里有链接,BLAHnumber和BLAHpath。它不会下载这些信息,事实上一旦你投入生产,你不能改变它。因此,新模式需要成为新的记录类型,并且需要注意现场更新,以确保您的应用程序落后。兼容。希望有助于使事情更清楚一些。

这篇文章https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit在很大程度上谈论了整个主题。原子提交,其中一个问题在这里特别提到。

+0

谢谢这个答案很多,我看到你的错误处理各种事情,很棒。 iCloudKit框架为我们处理本地存储(我目前有一个SqlLite数据库),说没有网络访问和记录不能提交? – Jules

+0

本地存储,不确定我是否理解你的问题。尽管我认为答案是否定的。您当然可以使用像Core Data这样的东西,它可以在框架内处理本地存储。你当然也可以在iCloud框架中使用SQL类型的查询,所以也许至少部分地回答你的问题。 – user3069232

+0

我的意思是,我可以仅依靠iCloud数据库功能,还是需要缓存数据并挂上可能尚未提交给iCloud的任何交易? – Jules