Я нашел, реализовал и протестировал «обходной путь» для (явно) автоматического увеличения номера значка приложения, который отлично работает с неповторяющимися локальными уведомлениями
Действительно, для UILocalNotifications невозможно, чтобы iOS «автоматически» обновляла / увеличивала номер значка при срабатывании нескольких локальных уведомлений, и пользователь «игнорирует» их или не обрабатывает их немедленно, поэтому они «накапливаются» в Центре уведомлений.
Кроме того, «добавление какого-либо метода обратного вызова» в ваше приложение не может позаботиться об «автоматическом увеличении», потому что весь процесс уведомлений обрабатывается «вне» вашего приложения iOS, ваше приложение даже не должно запускаться.
Однако есть некоторый обходной путь, основанный на знаниях, которые я нашел во время экспериментов, потому что документация XCode слишком расплывчата в свойстве значка.
- значок - это просто "целое число", на самом деле оно больше похоже на "фиктивную метку", которую вы назначаете свойству applicationIconBadgeNumber непосредственно перед регистрацией уведомления. Вы можете присвоить ему любое значение - при срабатывании уведомления iOS добавит это значение к значку, независимо от того, какое значение вы установили во время регистрации уведомления. Там нет никакого волшебного «автоинкремента» или других манипуляций с iOS (возможно, это отличается от push-уведомлений, но это не предмет здесь). 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, так что вы также можете оставлять комментарии, если я не соблюдаю «правила» здесь