2017-06-14 24 views
1

オブジェクトの作成または更新に関するプッシュ通知を発生させる特定のクラスに対してCloudKitサブスクリプションを作成しました。iOS - プッシュ通知が期待通りに応答しない

このコードは以下の通り行く:

// Create the predicate 
let predicate = NSPredicate(format: "recordId = %@", RECORD_ID) 

// Create a subscription specifying the record type, predicate and notification options 
let subscription = CKQuerySubscription(recordType: "Notes", predicate: predicate, options: [.firesOnRecordUpdate, .firesOnRecordCreation]) 

// Create a CloudKit notification object 
let notificationInfo = CKNotificationInfo() 
notificationInfo.shouldBadge = true 

// Set the subscriptor's notification object to the new CloudKit notification object 
subscription.notificationInfo = notificationInfo 

// Save the subscription to the database 
let publicDatabase = CKContainer.default().publicCloudDatabase 
publicDatabase.save(subscription) { (subs, err) in 
    if let err = err { 
     print("Failed to save subscription:", err) 
     return 
    } 
} 

サブスクリプションがサーバーに正常に保存されます。

私は黙っ通知を作成したい、と(受信時)私は次のように通知を処理しています:

import UserNotifications 

// Register for push notifications 
let notificationCenter = UNUserNotificationCenter.current() 
notificationCenter.requestAuthorization(options: [.badge, .alert, .sound]) { (success, err) in 
    if let err = err { 
     print("Failed to request oauth for notifications:", err) 
    } 
} 
application.registerForRemoteNotifications() 

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
    print("didRegisterForRemoteNotificationsWithDeviceToken:", deviceToken) 
} 

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { 
    print("Failed to register notifications_ error:", error) 
} 

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { 
    print("------------------------") 
    print("Receiving updates from the server") 

    // Convert the userInfo parameter to a CKNotification object 
    let cloudKitNotification = CKNotification(fromRemoteNotificationDictionary: userInfo) 

    // Get the body of the notification 
    let alertBody = cloudKitNotification.alertBody 
    print("alertBody:", alertBody ?? "") 

    // Get the new or modified record form the CKQueryNotification object 
    if cloudKitNotification.notificationType == CKNotificationType.query { 
     guard let queryNotification = cloudKitNotification as? CKQueryNotification else { 
      print("could not cast the query notification") 
      return 
     } 
     let recordId = queryNotification.recordID 
     print("recordId:", recordId ?? "") 
    } 
} 

問題が起こるのはここです。

私がこのアプリを使用していて、アップデートがサーバーに送信された場合、didReceiveRemoteNotificationが起動し、すべて正常に動作しますが、アプリがバックグラウンドにある場合、プッシュ通知が発生するとapp_notificationバッジが1 didReceiveRemoteNotificationは受信されません。

私の質問は、到着時にプッシュ通知エントリを処理するにはどうすればいいですか?

私はApp downloads content from the networkApp downloads content in response to push notifications

私は何のプッシュ通知を受信しないfalseに私のnotificationInfo.shouldBadgeを設定した場合、私は、気づいたもう一つとInfo.plisファイルにRequired background modesを設定しました。

+0

この問題を回避する方法についてのヒントはありますか? –

答えて

1

通知をすることができます、あなたのアプリケーションが動作しているときに、通知を受けない場合でも、ユーザーは機内モードに入る場合は特に、到着する保証など、接続を失ったとされていない助けるため

感謝処理を実行しません。つまり、処理を待っている通知(アプリケーションに参加していない間に受け取った通知だけでなく、何らかの理由でプッシュ通知を受け取ったことのない通知)を開始するたびに、アプリケーションを開始する必要があります。

アプリを起動するときは、CKFetchNotificationsChangesOperationを発行して、まだ処理していない新しい通知を探してください。

CKFetchNotificationChangesOperation操作を作成し、notificationChangedBlockを設定します。このブロックは、サーバーから取得された通知ごとに1回呼び出されます。すでに「読み込み済み」としてマークされているかどうかを評価することができます。そうでない場合は、通常はdidReceiveRemoteNotificationで行います。

任意で、サーバーからすべての通知がフェッチされた後、操作の最後に1回発生するコードをfetchNotificationChangesCompletionBlockに設定することもできます。

+0

そう言うことができます。私は3つのプッシュ通知を保留中のユーザープロファイルのデータを更新しました。私が別のデバイスにアプリを入力し、保留中のOPをチェックすると、保留中のOPが3つあると言うことになります。私は確認することができますそのサブスクリプションIDで言うことができますし、それらがすべて同じ場合私は最新のものを取得することができますか?この場合、最新のものを取り出す代わりに 'fetchNotificationChangesCompletionBlock'を使うべきだと思いますか?特定のタイプのサブスクリプションだけであるため、すべてを繰り返し処理する必要はありません。 –

+0

私はあなたが言っていることを理解しています。なぜなら、これらの補完ブロックを見ると、notifを実際に受け取った唯一のブロックなので、あなたはまだnotificationCangedBlockを反復処理する必要があると思います。notifsは最終的な補完ブロックに渡されないので、自分で収集する必要があります。 2つのことが役に立ちます:最初のブロックで受け取ったnotifは、読み込み/未読(処理時に状態を更新すると仮定して)とマークされます。次に、 – Thunk

+0

...操作は、変更トークンで開始することができます。変更トークンは、基本的には以前読んだことを示す「読み取りポインタ」です。したがって、毎回変更トークンを保存して、受け取った最新のトークンで後続の呼び出しを開始する場合は、ウェイドしなければならないnotifの数を絞り込む必要があります。しかし、私は絶対的な最後のものだけを単に取る方法を知らない。 – Thunk

関連する問題