Aplicativo iOS: como limpar notificações?

109

Tenho um aplicativo iOS para o qual algumas notificações push são enviadas. Meu problema é que as mensagens / notificações permanecem na Central de Notificações no iOS depois de serem tocadas. Como posso remover uma notificação do meu aplicativo na Central de Notificações na próxima vez que o aplicativo for aberto?

Me deparei com postagens onde as pessoas estão ligando setApplicationIconBadgeNumberpara um valor zero para limpar as notificações. Isso me parece muito estranho, então acredito que talvez exista outra solução?

EDIT1:

Estou tendo problemas para limpar as notificações. Por favor, veja meu código aqui:

- (void) clearNotifications {
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (launchOptions != nil)
    {
        NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (dictionary != nil)
        {
            NSLog(@"Launched from push notification: %@", dictionary);

            [self clearNotifications];
        }
    }

    return YES;
}

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{    
    NSLog(@"Received notification: %@", userInfo);
    [self clearNotifications];
}

Estou executando o aplicativo através do Xcode. Quando o aplicativo é minimizado e eu inicio o aplicativo usando a notificação na Central de notificações, posso ver no log que o didReceiveRemoteNotificationé chamado e, usando pontos de interrupção, posso ver que o clearNotificationsfoi executado. Mas ainda assim a notificação trava na Central de Notificações. Por quê?

dhrm
fonte

Respostas:

157

Muito provavelmente porque a Central de Notificações é um recurso relativamente novo, a Apple não queria necessariamente empurrar um novo paradigma para limpar notificações. Em vez disso, eles se propuseram [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];a limpar essas notificações. Pode parecer um pouco estranho e a Apple pode fornecer uma maneira mais intuitiva de fazer isso no futuro, mas por enquanto é a forma oficial.

Eu mesmo uso este snippet:

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];

que nunca falha em limpar todas as notificações do aplicativo da Central de Notificações.

Patrick Perini
fonte
cancelAllLocalNotifications is Deprecated - developer.apple.com/documentation/uikit/uiapplication/… Você precisa usar let center = UNUserNotificationCenter.current() center.removeAllDeliveredNotifications() // To remove all delivered notifications stackoverflow.com/a/40397907/1155650
Rohit Vipin Mathews
119

Só para expandir a resposta da pcperini. Como ele menciona, você precisará adicionar o código a seguir ao seu application:didFinishLaunchingWithOptions:método;

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];

Você também precisa aumentar e diminuir o emblema em seu application:didReceiveRemoteNotification:método se estiver tentando limpar a mensagem do centro de mensagens para que, quando um usuário entrar em seu aplicativo pressionando uma notificação, o centro de mensagens também apague, ou seja;

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
ADÃO
fonte
Acho que cancelAllLocalNotifications não é obrigatório. Funcionou para mim sem essa linha
Murali
@Murali isso dependeria de você usar notificações locais ou não ...?
Alejandro Iván
1
ATUALIZAÇÃO :: “cancelAllLocalNotifications 'está obsoleto: primeiro obsoleto no iOS 10.0” Portanto, se a versão do seu aplicativo for superior a iOS10.0, você deve usar este UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter]; [center removeAllDeliveredNotifications]; [center removeAllPendingNotificationRequests];
User18474728
21

Também pode fazer sentido adicionar uma chamada para clearNotifications em applicationDidBecomeActive para que, caso o aplicativo esteja em segundo plano e volte, também apague as notificações.

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self clearNotifications];
}
bert
fonte
15

Atualização para iOS 10 (Swift 3)

Para limpar todas as notificações locais em aplicativos iOS 10, você deve usar o seguinte código:

import UserNotifications

...

if #available(iOS 10.0, *) {
    let center = UNUserNotificationCenter.current()
    center.removeAllPendingNotificationRequests() // To remove all pending notifications which are not delivered yet but scheduled.
    center.removeAllDeliveredNotifications() // To remove all delivered notifications
} else {
    UIApplication.shared.cancelAllLocalNotifications()
}

Este código lida com a limpeza de notificações locais para iOS 10.x e todas as versões anteriores do iOS. Você precisará import UserNotificationspara o código iOS 10.x.

James Stonehill
fonte
9

Se você tiver notificações locais agendadas pendentes e não quiser usar cancelAllLocalNotificationspara limpar as antigas na Central de Notificações, você também pode fazer o seguinte:

[UIApplication sharedApplication].scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;

Parece que se você definir o, scheduledLocalNotificationsele apaga as antigas na Central de Notificações e, definindo-o para si mesmo, você retém as notificações locais pendentes.

ospr
fonte
1
Isso funciona perfeitamente para mim no iOS 9. Eu não queria cancelar todas as minhas notificações porque elas se repetem no tempo (diariamente ou semanalmente). E assim eu limpo todas as coisas sem excluí-las.
superpuccio
1
Melhor solução que vi até agora. Alguém sabe se funciona no iOS 8?
duncanc4
@ duncanc4 da última vez que testei no iOS 8, ele estava funcionando.
ospr
Onde dentro do aplicativo você chamaria isso?
Alex Zavatone
Alex, você deve chamá-lo sempre que precisar limpar as notificações na Central de Notificações. Eu o chamo tanto no meu AppDelegate applicationDidBecomeActive:quanto nos application:didReceiveLocalNotification:métodos.
ospr de
3

Em Swift, estou usando o seguinte código dentro do meu AppDelegate:

func applicationDidBecomeActive(application: UIApplication) {
    application.applicationIconBadgeNumber = 0
    application.cancelAllLocalNotifications()
}
Antoine
fonte
3

Se você vem aqui pensando o contrário (como eu estava), este post pode ser para você.

Não consegui descobrir por que minhas notificações foram apagadas quando eu limpei o crachá ... Eu incremento manualmente o crachá e quero limpá-lo quando o usuário entrar no aplicativo. No entanto, isso não é motivo para limpar o centro de notificação; eles ainda podem querer ver ou agir de acordo com essas notificações.

O negativo 1 resolve o problema, felizmente:

[UIApplication sharedApplication].applicationIconBadgeNumber = -1;
TahoeWolverine
fonte
1
Funciona para você no iOS9? Não notei nenhuma diferença em definir um emblema como 0 ou -1. Ele ainda limpa todas as notificações remotas no meu caso.
AlexeyVMP
Sim, na verdade comecei a notar isso com meu aplicativo novamente; Não tenho ideia do que mudou.
TahoeWolverine
Estou desistindo, pois a Apple decidiu de alguma forma que o aplicativo sem número de selo não deveria ter notificações
AlexeyVMP
1

Talvez no caso de haver alarmes programados e emblemas de ícones de aplicativos não apagados.

NSArray *scheduledLocalNotifications = [application scheduledLocalNotifications];
NSInteger applicationIconBadgeNumber = [application applicationIconBadgeNumber];

[application cancelAllLocalNotifications];
[application setApplicationIconBadgeNumber:0];

for (UILocalNotification* scheduledLocalNotification in scheduledLocalNotifications) {
    [application scheduleLocalNotification:scheduledLocalNotification];
}
[application setApplicationIconBadgeNumber:applicationIconBadgeNumber];
Jong Su Park
fonte
0

Quando você tiver notificações repetidas no futuro, você não deseja cancelar essas notificações, você pode limpar o item na central de notificações:

func clearNotificationCenter() {
    UIApplication.sharedApplication().applicationIconBadgeNumber = 1
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}

Você não pode limpar a notificação quando seu aplicativo está aberto em primeiro plano chamando o método abaixo imediatamente após receber a notificação local, caso contrário, você receberá dezenas de centenas de notificações. Talvez porque a mesma notificação se aplique novamente e agora é a hora de disparar, então continue atirando, aplique novamente, dispare, aplique ....:

[UIApplication sharedApplication].scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
zgjie
fonte
0

Ao fazer logout de seu aplicativo, você deve usar uma linha de código abaixo no método de clique do botão de logout.

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];

[[UIApplication sharedApplication] cancelAllLocalNotifications];

e isso funciona perfeitamente no meu aplicativo.

Vaibhav Shiledar
fonte
0

Você precisa adicionar o código abaixo em seu applicationDidBecomeActivemétodo AppDelegate .

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
Bhavesh Patel
fonte
-1

Peguei daqui . Funciona para iOS 9

UIApplication *app = [UIApplication sharedApplication];
NSArray *eventArray = [app scheduledLocalNotifications];
for (int i=0; i<[eventArray count]; i++)
{
    UILocalNotification* oneEvent = [eventArray objectAtIndex:i];
    //Cancelling local notification
    [app cancelLocalNotification:oneEvent];
}
Dan L
fonte