アプリアイコンのバッジ番号を(明らかに)自動インクリメントするための「回避策」を見つけ、実装し、テストしました。これは、繰り返されないローカル通知で正常に機能します。
実際、UILocalNotificationsは、複数のローカル通知が発生したときにiOSがバッジ番号を「自動的に」更新/インクリメントすることはできません。ユーザーはそれらを「無視」するか、すぐに処理しないため、通知に「積み上げ」ます。中心。
また、アプリに「コールバックメソッドを追加する」と「自動インクリメント」を処理できません。通知全体がiOSによってアプリの「外部」で処理されるため、アプリを実行する必要さえありません。
ただし、XCodeのドキュメントがバッジのプロパティについてあいまいすぎるため、実験を通じて見つけた知識に基づいた回避策がいくつかあります。
- バッジは単なる「整数」であり、実際には、通知を登録する直前にapplicationIconBadgeNumberプロパティに割り当てる「ダミーラベル」に似ています。任意の値を指定できます。通知が発生すると、通知の登録時に設定した値に関係なく、iOSはその値をバッジに追加します。iOSによる魔法の「自動インクリメント」やその他の操作はありません(プッシュ通知とは異なるかもしれませんが、ここでは主題ではありません)。iOSは、登録された通知から番号(整数)を取得し、バッジに入れます。
したがって、「回避策」として、アプリは、「保留中の通知に加えて」新しく作成および登録する通知ごとに、正しい増分バッジ番号をすでに提供している必要があります。
アプリは将来を見ることができず、すぐに処理するイベントと、しばらくの間「保留中」のままにするイベントを知ることができないため、いくつかのトリックがあります。
通知がアプリによって処理される場合(通知、アイコンなどをタップすることにより)、次のことを行う必要があります。
- 保留中のすべての通知のコピーを取得する
- これらの保留中の通知のバッジ番号を「再番号付け」します
- 保留中の通知をすべて削除する
- 通知のコピーを修正されたバッジ番号で再登録します
また、アプリが新しい通知を登録するときは、最初に保留中の通知の数を確認し、次のコマンドで新しい通知を登録する必要があります。
badgeNbr = nbrOfPendingNotifications + 1;
私のコードを見ると、より明確になります。私はこれをテストしました、そしてそれは間違いなく働いています:
'registerLocalNotification'メソッドでは、次のことを行う必要があります。
NSUInteger nextBadgeNumber = [[[UIApplication sharedApplication] scheduledLocalNotifications] count] + 1;
localNotification.applicationIconBadgeNumber = nextBadgeNumber;
通知(appDelegate)を処理するときは、以下のメソッドを呼び出す必要があります。このメソッドは、アイコンのバッジをクリアし、保留中の通知(ある場合)のバッジの番号を付け直します。
次のコードは、「シーケンシャル」に登録されたイベントに対して正常に機能することに注意してください。保留中のイベントの間にイベントを「追加」する場合は、最初にこれらのイベントを「再ソート」する必要があります。そこまでは行きませんでしたが、可能だと思います。
- (void)renumberBadgesOfPendingNotifications
{
// clear the badge on the icon
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
// first get a copy of all pending notifications (unfortunately you cannot 'modify' a pending notification)
NSArray *pendingNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
// if there are any pending notifications -> adjust their badge number
if (pendingNotifications.count != 0)
{
// clear all pending notifications
[[UIApplication sharedApplication] cancelAllLocalNotifications];
// the for loop will 'restore' the pending notifications, but with corrected badge numbers
// note : a more advanced method could 'sort' the notifications first !!!
NSUInteger badgeNbr = 1;
for (UILocalNotification *notification in pendingNotifications)
{
// modify the badgeNumber
notification.applicationIconBadgeNumber = badgeNbr++;
// schedule 'again'
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
}
真に「防弾」であるためには、このメソッドは「アトミック」(カーネル)コードである必要があり、このメソッドの実行中にiOSが通知を起動しないようにします。ここでこのリスクを冒さなければなりません。これが起こる可能性は非常に小さいです。
これはStackoverflowへの私の最初の貢献なので、ここで「ルール」に従わない場合にもコメントできます