2017-02-26 12 views
0

最初に、ユーザーがプッシュ通知を受け入れる要求を拒否した場合、どのようにこれを評価することができますか?iOS、iCloudKit取引の通知通知を処理する方法は?

私はそれがベータ版だったと思うが、サイレント通知に問題があったようです何を読んでから、この問題は修正されました。私はこれが通知許可メッセージが表示されます、サイレント通知をキャプチャするregisterForRemoteNotificationsを呼び出すとき

私は、子供のアプリを開発しています。

私はまた、ユーザーはまれにしかインターネットへのアクセスを持っている場合のiCloudデータベースのセットアップと何が起こるかと思いまして。私は彼らがアプリケーションを最初にダウンロードしたときに持っていなければならないと思いますが、ダウンロードした後に決してアプリケーションを実行しないと、データベーススキーマをどのように取得しますか?これは私たちが処理しなければならないものであり、ユーザーにインターネットに接続するよう求めるものですか?

私はこれの多くは仮定のですけど、明らかに我々はこれをキャプチャし、処理する必要があります。

誰もが指摘すると役に立つかもしれ役に立つポッドことができれば、私も感謝されると思います。

+0

私の質問に答えると、バグが修正されています。http://stackoverflow.com/questions/31108576/cloudkit-push-notifications-on-record-update-stopped-working – Jules

答えて

1

ジュール、

あなたはそんなにこの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作成コール第四行からレコードタイプが来ますこの場合、「曖昧さ」と呼ばれます。

その中のフィールド[スキーマ]は、私がここで行うようにコードの詳細を記述する必要があります。この場合、リンク、BLAHnumber、およびBLAHpathがあります。この情報はダウンロードされず、実際に運用に移行すると変更することはできません。したがって、新しいスキーマは新しいレコードタイプである必要があり、現行のものへのフィールド更新に注意する必要があります。互換性があります。物事を少しはっきりさせるのに役立つことを願っています。全体の主題について多くのことを詳細に

この記事https://www.shinobicontrols.com/blog/ios8-day-by-day-day-33-cloudkit会談。原子コミット、あなたの質問の1つがここに特に言及されています。

+0

ありがとうそれは多くの人に答えてくれます。私はさまざまなことをあなたの間違いに伝えます。 iCloudKitフレームワークはローカルストレージを処理しています(私は現在SqlLiteデータベースを持っています)。ネットワークアクセスがなく、レコードをコミットできないとしますか? – Jules

+0

ローカルストレージ、ご質問が分かりません。私は答えは「いいえ」だと思いますが、もちろんCore Dataのようなものを使用することもできます。これは、フレームワーク内のローカルストレージを扱うためのものです。もちろん、iCloudフレームワーク内でSQLタイプのクエリを使用することもできます。多分、あなたの質問に少なくとも部分的に答えます。 – user3069232

+0

つまり、iCloudデータベースの機能だけに頼ることはできますか、またはデータをキャッシュしてiCloudにコミットされていないトランザクションにハングアップする必要がありますか? – Jules

関連する問題