私は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)
}
}
をそしてここで私はAppDelegate
でdidReceiveRemoteNotification:
の内側にそれを使用します:
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
RuntimeUtils.delay(seconds: 0.2, closure: {
completionHandler(.newData)
})
completionHandlerにこの遅延を追加した後
これは私が簡単にどこからでも何かを遅らせるために作成したクラスや関数でありますそれは通知の削除後に常に実行され、デバッガが接続されているかどうかに関係なく、毎回動作するようです。
これは厄介な問題でした。
出典
2017-12-07 12:49:21
Sti
良いヒント!各通知には、削除すべきIDを識別するカスタムIDフィールドが含まれます。しかし、このアプリはiOS 9までサポートしなければならず、私が集めたものから、私は 'UNUserNotificationCenter'を使うことができません:(しかし素晴らしい答え! – Sti
@Stiありがとう、正直言って、あなたはiOSこれについては9つですが、iOS 10以前では可能ではなかったと思いますが、とにかく、この機能をiOS 10以上でサポートすることはできますが、iOS 9の場合はデフォルトの動作にする必要があります。 – TawaNicolas
フォローアップの質問..アプリケーションのどの部分がサイレント通知から「起きる」のですか?私はコードをどこに置くべきか分かりません。 – Sti