2017-10-11 26 views
0

私は遠隔通知を読んでいて、ついにそれを機能させました。私たちのアプリは私たちのサーバーから通知を受けています。サーバー上で特定の条件が満たされている場合(たとえば、通知が有効でないなど)、未読の通知を削除または更新する必要があります。私は、「サイレント」通知が唯一の方法だと理解していますが、私はまだ方法について混乱しています。 サイレント通知によって私のアプリが起動するようになった場合、ローカルの通知をスケジュールすることはできますが、既存のリモート通知を削除することはできますか?iOSのリモートプッシュ通知をクリアするには?

サーバーからのサイレント通知を排他的に使用する唯一のソリューションは、すべて通知をローカルの通知としてスケジュールし、後で削除することができますか? 例:火を使わないでください&この機能が必要な場合、サーバーからデバイスへのリモートプッシュ通知を忘れてしまいますか?

編集:

のObjective-Cを:あなたのアプリがサイレント通知からウェイクアップした後、あなたが使用して、受信した通知をループに必要/

答えて

0

私はhis answerで提案されたTawaNicolasのようにして、受信通知をgetDeliveredNoti....としてから、すべての通知のuserInfoを調べて、削除したいものを見つけました。私は取り外し可能な通知の識別子を配列に格納し、removeDelivered...と呼んでいました。

これは彼の答えが示しているとおりですが、これは最初は機能しませんでした。私はまだそれを修正していることは完全にはわかっていませんが、テストでは動作していることが示されています。私の解決策はやや理にかなっています。

didReceiveRemote..の機能の中にあったのは、最後にcompletionHandler(.newData)に電話する必要があります。これは、NotificationCenterに何かが変更されたことを通知するためです。このコールバックがと呼ばれる前に、の前にリムーバブル通知が実際に削除されたと思われました。私は文書をチェックし、removeDeliveredNotificationsは確かに非同期です。

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs) 
completionHandler(.newData) 

最初の関数は、第2の機能を呼び出す前に完了したことを保証されていない:これは私がこれを行うとすることを意味します。これは、自分のNotificationCenterに何かが更新されたことを伝えるcompletionHandlerが最初に完了し、その後通知がシステムから削除されることを意味します。 (NotificationCenterは、その関数の後にUIを更新するために、独自のcompletionHandlerを呼び出すのではないようです)。

すべてこのとなる場合があります。私が経験していたように。デバッガに接続すると、completionHandlerが呼び出される前に常に完了するように、removeDeliveredNotifications関数が非常に速くなりました。つまり、システムを更新する前に通知が削除されました。だから、これを開発するときはすべてが素晴らしかったです。デバッガとの接続を解除すると、removeDeliveredNotifications関数が若干遅くなりました。非同期なので、の後にを呼び出しました。completionHandlerが呼び出されました。システムの更新が早す​​ぎます。

これを解決する最善の方法は、AppleがremoveDeliveredNotificationsのcompletionBlockを与え、その内部にcompletionHandlerを呼び出すことです。

これを解決するには、固定遅延0.2秒を追加して汚れてしまった。それはおそらく0.2よりも低いかもしれませんが、私たちがやっていることのためには、やはり2度目にはそれほど重要ではありません。

class RuntimeUtils{ 
    class func delay(seconds delay:Double, closure:@escaping()->()){ 
     DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay*Double(NSEC_PER_SEC)))/Double(NSEC_PER_SEC), execute: closure) 
    } 
} 

をそしてここで私はAppDelegatedidReceiveRemoteNotification:の内側にそれを使用します:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs) 
RuntimeUtils.delay(seconds: 0.2, closure: { 
    completionHandler(.newData) 
}) 

completionHandlerにこの遅延を追加した後

これは私が簡単にどこからでも何かを遅らせるために作成したクラスや関数でありますそれは通知の削除後に常に実行され、デバッガが接続されているかどうかに関係なく、毎回動作するようです。

これは厄介な問題でした。

1

:このアプリは、iOSの9までサポートしています

[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) { 

}]; 

スウィフト:

UNUserNotificationCenter.current().getDeliveredNotifications { (notifications: [UNNotification]) in 

} 

各通知のrequest.content.userInfoプロパティを確認して、削除する通知があるかどうかを確認します。

のObjective-Cは:

[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[identifier]]; 

スウィフト:identifiernotification.request.identifierプロパティです

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier]) 

はその後、あなたは通知センターからそれを削除するには、以下を使用します。

編集:適切な通知を識別するには、ペイロードで送信した内容を確認する必要があります。これはuserInfoで、正しいものを識別できます。 (たぶん、ユーザーIDまたはのeventIDか?これは、プロジェクトによって異なります。)あなたはUNUserNotificationCenter.current().getDeliveredNotificationsおよび/またはUNUserNotificationCenter.current().removeAllDeliveredNotifications

を使用することができiOS版> = 10の場合

+0

良いヒント!各通知には、削除すべきIDを識別するカスタムIDフィールドが含まれます。しかし、このアプリはiOS 9までサポートしなければならず、私が集めたものから、私は 'UNUserNotificationCenter'を使うことができません:(しかし素晴らしい答え! – Sti

+0

@Stiありがとう、正直言って、あなたはiOSこれについては9つですが、iOS 10以前では可能ではなかったと思いますが、とにかく、この機能をiOS 10以上でサポートすることはできますが、iOS 9の場合はデフォルトの動作にする必要があります。 – TawaNicolas

+0

フォローアップの質問..アプリケーションのどの部分がサイレント通知から「起きる」のですか?私はコードをどこに置くべきか分かりません。 – Sti

1

あなたはそれが新しいいいです、同様import UserNotificationsを追加する必要があります通知フレームワーク。

+0

ああ、おしゃれですが、私たちのアプリはiOS 9までサポートしています:( – Sti

関連する問題