Обновить значок с push-уведомлением, пока приложение работает в фоновом режиме

82

У меня работает push-уведомление, и мне удалось обновить счетчик значков, когда приложение выводится на передний план.

Я немного запутался в этом ... iPhone получает уведомление, и появляется всплывающее сообщение для активации моего приложения, а значок обновляется только после запуска приложения.

Это звучит неправильно с точки зрения пользовательского опыта. Насколько я понимаю, счетчик значков должен уведомлять пользователя о том, что требует действий, посредством увеличения счетчика, но этого не произойдет до более позднего этапа, когда приложение будет запущено.

Итак, есть ли способ сообщить приложению, чтобы оно обновляло счетчик значков при получении push-уведомлений и в фоновом режиме?

Обратите внимание, что мое приложение не использует данные о местоположении и что у меня есть UIRemoteNotificationTypeBadgeзапрос на регистрацию.

Ура AF

Abolfoooud
источник
Вы хотите, чтобы значок отображался на значке приложения?
Аман Аггарвал
Я показываю количество на вкладках. И столкнулся с той же проблемой. Когда приложение работает в фоновом режиме, счетчик не увеличивается. Как установить?
Srusti Thakkar

Ответы:

79

Поскольку push-уведомления обрабатываются iOS, а не вашим приложением, вы не можете изменить значок приложения при получении push-уведомления.

Но вы можете отправить номер значка в полезной нагрузке push-уведомления, но вам придется выполнять расчет на стороне сервера.

Вам следует прочитать Руководство по программированию локальных и push-уведомлений и особенно полезные данные уведомления .

Полезная нагрузка может выглядеть так:

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9
    }
}

Теперь значок значка приложения покажет 9.

rckoenes
источник
4
Я уже делаю это ... но это значение получается только тогда, когда мое приложение выводится на передний план, которое я позже использую для обновления значения значка с помощью [UIApplication sharedApplication] .applicationIconBadgeNumber = count;
Abolfoooud
7
Нет, вам нужно установить номер значка в полезных данных push-уведомления.
rckoenes
11
Я еще раз взглянул на свою структуру полезной нагрузки, и, похоже, я передавал значение параметра значка как строку '4', а не как int 4 !!! Теперь у меня все работает ... спасибо за помощь
Abolfoooud
Я тестировал, что он не работает при изменении значка структуры полезной нагрузки
wod
1
@wod, что вы имеете в виду: изменение значка структуры полезной нагрузки.
rckoenes
11

Мы можем изменить номер значка, когда находимся в фоновом режиме, отправив параметр «badge» в пакете push-уведомлений. Как указал @rckoenes, JSONпараметр для значка должен быть INTEGER .

Пример кода PHP для того же

// Create the payload body
$body['aps'] = array(
        'alert' => $message,
        'badge' => 1,
        'sound' => 'default'
        );

badge => 1 где 1 - целое число, а не строка (т.е. без апострофов)

Праджул
источник
11

На самом деле в iOS 10 удаленное уведомление будет автоматически вызывать didReceiveRemoteNotificationметод в вашем AppDelegate.

У вас есть 2 способа обновить счетчик значков в фоновом режиме.
Я сделал это и для своего текущего приложения. Вам также не нужно расширение службы уведомлений.

1-й способ:

Отправьте ключ значка APS с данными в APN.
Это обновит счетчик значков в соответствии с вашим значением Integer в полезной нагрузке значка. пример:

// Payload for remote Notification to APN
{
    "aps": {
        "content-available": 1,
        "alert": "Hallo, this is a Test.",
        "badge": 2, // This is your Int which will appear as badge number,
        "sound": default
    }
}

2-й способ:

Вы можете переключить свой application.applicationState и обновить количество значков, когда applicationState находится внутри .background. НО вы должны позаботиться о том, чтобы не устанавливать параметр ключа значка в своей полезной нагрузке уведомления при отправке в APN ex

// Payload to APN as silent push notification
{
    "aps": {
        "content-available": 1
    }
}

Обработайте обновление значка в соответствии с состоянием приложения:

Вот мой рабочий код для обновления счетчика значков без ключа значка в полезной нагрузке для APN.

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    print("APN recieved")
    // print(userInfo)
    
    let state = application.applicationState
    switch state {
        
    case .inactive:
        print("Inactive")
        
    case .background:
        print("Background")
        // update badge count here
        application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1
        
    case .active:
        print("Active")

    }
}

Сбросить количество значков:

Не забудьте сбросить счетчик значков, когда ваше приложение вернется в активное состояние.

func applicationDidBecomeActive(_ application: UIApplication) {
    // reset badge count
    application.applicationIconBadgeNumber = 0
}
Гкиокан
источник
Как обновить значок, если приложение не работает в фоновом режиме?
Нагендра Рао
1
Если вы отправите APS с ключом, доступным для содержимого, он запустит метод didReceiveRemoteNotification независимо от состояния приложения. Просто попробуйте с родным устройством. Если у вас iOS, вы можете использовать этот инструмент для отправки вашего JSON-объекта в APN: github.com/noodlewerk/NWPusher
Gkiokan
вау, отлично, а что, если я отправляю уведомление, когда контент недоступен? (который касается любого не фонового уведомления). didReceiveRemoteNotificationне называется
StackExploded
6
    **This is the APNS payload get back from server.**

    {
        "aps" : {
            "alert" : "You got your emails.",
            "badge" : 9,
            "sound" : "bingbong.aiff"
        },
        "acme1" : "bar",
        "acme2" : 42
    }

Значение значка ключа автоматически считается количеством значков. На стороне приложения ios нет необходимости рассчитывать или обрабатывать количество. В приведенном выше примере 9 - это количество значков, поэтому на значке вашего приложения будет отображаться 9.

ПРИМЕЧАНИЕ Пока ваше приложение закрыто, вы не можете самостоятельно обрабатывать значки. Вот почему мы используем ключ значка из APNS Payload. Более подробные сведения об уведомлении см. В документации.

если вы хотите уменьшить количество значков самостоятельно, уменьшите количество и обновите его самостоятельно. следующим образом

Прабхат Панди
источник
4

Если вы используете NotificationServiceExtension, вы можете обновить значок в нем.

var bestAttemptContent : UNMutableNotificationContent? // 
bestAttemptContent.badge = 0//any no you wanna display

Каждый раз, когда ваше приложение получает уведомление, будет вызываться ваше расширение службы. Сохраните это значение в пользовательском значении по умолчанию и отобразите его. Чтобы поделиться пользовательскими настройками по умолчанию между приложением и расширением, вам необходимо включить группу приложений в приложении. Подробнее здесь

Сурджит Раджпут
источник
вы можете сохранить это количество уведомлений на сервере и отправить его с уведомлением.
Сурджит Раджпут
Я использую Firebase Cloud Messaging, знаете, как это сделать?
Ghiggz Pikkoro
3

Начиная с iOS 10 вы можете разработать расширение службы уведомлений для своего приложения. Он будет запущен системой, когда вы получите уведомление, и вы сможете вычислить действительный номер для значка и установить его.

Взгляните на документацию: https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension

Михаил Крутоярский
источник
1

Для Firebase Cloud Messaging (FCM) это должно быть так:

{
  "to": "some_token",

  "notification": {
    "body": "this is a body",
    "title": "this is a title",
    "badge" : 1
  }, 

  "priority": "high", 
}
Александр Бабич
источник
0
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    application.applicationIconBadgeNumber = 0;
    NSLog(@"userInfo %@",userInfo);

    for (id key in userInfo) {
        NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
    }

    [application setApplicationIconBadgeNumber:[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]];
    NSLog(@"Badge %d",[[[userInfo objectForKey:@"aps"] objectForKey:@"badge"] intValue]);
}
Суви
источник
Почему вы используете intValue вместо integerValue, которое является NSInteger? @property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
Alex Zavatone
0

Как сказал @rckoenes, вам нужно будет выполнить вычисление на стороне сервера, но как вы могли узнать, когда увеличить значение номера значка, которое вы должны отправить в полезной нагрузке ?.

Будет ли, когда вы запускаете приложение, отправлять на ваш сервер сообщение, указывающее, что приложение запущено. Итак, на стороне сервера вы снова начинаете со значка = 0, и пока сервер не получает сообщений, увеличивайте номер значка с каждой полезной нагрузкой push-уведомления.

Мустафа
источник
0

в полезной нагрузке apns необходимо указать "доступный контент": 1 для количества значков обновления в фоновом режиме

func application(_ application: UIApplication, didReceiveRemoteNotification 
   userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {


// increase badge count, but no need if you include content-available

application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1

}

func applicationDidBecomeActive(_ application: UIApplication) {

// reset badge count

application.applicationIconBadgeNumber = 0

}

например, для

"aps":{
    "alert":"Test",
    "sound":"default",
    "content-available":1

}
Прашант Кумар
источник
цель content-available = 1 - беззвучное уведомление, а не для значка.
Manish
0

в устаревшей его работе «бейджик» установлен кол-во

{
  "to": "token",
  "notification": {
    "title": "Example",
    "body": "Tiene 22 actualizaciones.",
    "badge":278
  },
  "data": {
    "story_id": "story_12345",
    "count_vaca":22
  }
}
Хавьер Дж. Солис Флорес
источник
-1

После получения удаленного уведомления при открытии приложения,

получить текущий номер значка в " didBecomeActive" способе вашего AppDelegate.

Файл с использованием кода ниже:

int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badgeCount = badgeCount + 1;
Вед Гупта
источник
3
Это не сработает, пока пользователь не коснется приложения или уведомления, чтобы запустить приложение. Он не будет делать то, что хочет OP, обновлять значок, когда приложение находится в фоновом режиме и до того, как пользователь взаимодействует с приложением или уведомлением.
Alex Zavatone