Aplikacja na iOS: jak wyczyścić powiadomienia?

109

Mam aplikację na iOS, do której wysyłane są powiadomienia push. Mój problem polega na tym, że wiadomości / powiadomienia pozostają w Centrum powiadomień w iOS po dotknięciu. Jak mogę usunąć powiadomienie o mojej aplikacji w Centrum powiadomień przy następnym uruchomieniu aplikacji?

Natknąłem się na posty, w których ludzie dzwonią setApplicationIconBadgeNumberdo wartości zerowej, aby wyczyścić powiadomienia. Wydaje mi się to bardzo dziwne, więc wierzę, że może istnieje inne rozwiązanie?

EDYCJA1:

Mam problemy z wyczyszczeniem powiadomień. Zobacz mój kod tutaj:

- (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];
}

Uruchamiam aplikację przez Xcode. Kiedy aplikacja jest zminimalizowana i uruchamiam ją za pomocą powiadomienia w Centrum powiadomień, widzę w dzienniku, że didReceiveRemoteNotificationjest wywoływana i używając punktów przerwania, które widzę, że clearNotificationszostała uruchomiona. Ale nadal powiadomienie zawiesza się w Centrum powiadomień. Czemu?

dhrm
źródło

Odpowiedzi:

157

Najprawdopodobniej dlatego, że Centrum powiadomień jest stosunkowo nową funkcją, Apple niekoniecznie chciał naciskać zupełnie nowy paradygmat usuwania powiadomień. Zamiast tego postanowili [[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];wyczyścić wspomniane powiadomienia. Może się to wydawać nieco dziwne, a Apple może zapewnić bardziej intuicyjny sposób zrobienia tego w przyszłości, ale na razie jest to oficjalny sposób.

Ja używam tego fragmentu:

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

który nigdy nie przestaje czyścić wszystkich powiadomień aplikacji z Centrum powiadomień.

Patrick Perini
źródło
cancelAllLocalNotifications is deprecated - developer.apple.com/documentation/uikit/uiapplication/ ... Musisz użyć let center = UNUserNotificationCenter.current() center.removeAllDeliveredNotifications() // To remove all delivered notifications stackoverflow.com/a/40397907/1155650
Rohit Vipin Mathews
119

Aby rozwinąć odpowiedź pcperini. Jak wspomina, będziesz musiał dodać następujący kod do swojej application:didFinishLaunchingWithOptions:metody;

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

Musisz także zwiększyć, a następnie zmniejszyć znacznik w swojej application:didReceiveRemoteNotification:metodzie, jeśli próbujesz usunąć wiadomość z centrum wiadomości, aby gdy użytkownik wejdzie do aplikacji po naciśnięciu powiadomienia, centrum wiadomości również zostanie wyczyszczone, tj.

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
ADAM
źródło
Myślę, że cancelAllLocalNotifications nie jest wymagane. Pracowałem dla mnie bez tej linii
Murali
@Murali czy to zależałoby od Ciebie, korzystając z lokalnych powiadomień, czy nie ...?
Alejandro Iván
1
UPDATE :: „cancelAllLocalNotifications 'jest przestarzałe: najpierw przestarzałe w iOS 10.0” Jeśli więc twoja wersja aplikacji jest nowsza niż iOS 10.0, powinieneś użyć tego UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter]; [centrum removeAllDeliveredNotifications]; [centrum removeAllPendingNotificationRequests];
Użytkownik18474728
21

Sensowne może być również dodanie wywołania clearNotifications w applicationDidBecomeActive, aby w przypadku, gdy aplikacja jest w tle i wróci, wyczyści również powiadomienia.

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self clearNotifications];
}
bert
źródło
15

Aktualizacja dla iOS 10 (Swift 3)

Aby wyczyścić wszystkie powiadomienia lokalne w aplikacjach na iOS 10, użyj następującego kodu:

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()
}

Ten kod obsługuje czyszczenie lokalnych powiadomień dla iOS 10.xi wszystkich poprzednich wersji iOS. Będziesz potrzebował import UserNotificationskodu iOS 10.x.

James Stonehill
źródło
9

Jeśli masz oczekujące zaplanowane powiadomienia lokalne i nie chcesz używać cancelAllLocalNotificationsdo usuwania starych w Centrum powiadomień, możesz również wykonać następujące czynności:

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

Wygląda na to, że jeśli ustawisz scheduledLocalNotificationsto, wyczyści stare w Centrum powiadomień, a ustawiając je na siebie, zachowujesz oczekujące powiadomienia lokalne.

ospr
źródło
1
Działa to jak urok na iOS 9. Nie chciałem anulować wszystkich moich powiadomień, ponieważ powtarzają się w czasie (codziennie lub co tydzień). W ten sposób usuwam wszystkie rzeczy bez ich usuwania.
superpuccio
1
Najlepsze rozwiązanie, jakie do tej pory widziałem. Czy ktoś wie, czy działa na iOS 8?
duncanc4
@ duncanc4 ostatnim razem, gdy testowałem go na iOS 8, działało.
ospr
Gdzie w aplikacji można to nazwać?
Alex Zavatone
Alex, powinieneś do niego zadzwonić, ilekroć chcesz wyczyścić powiadomienia w Centrum powiadomień. Wołam to zarówno w moich AppDelegate, jak applicationDidBecomeActive:i application:didReceiveLocalNotification:metodach.
ospr
3

W Swift używam następującego kodu wewnątrz mojej AppDelegate:

func applicationDidBecomeActive(application: UIApplication) {
    application.applicationIconBadgeNumber = 0
    application.cancelAllLocalNotifications()
}
Antoine
źródło
3

Jeśli przyjeżdżasz tutaj i zastanawiasz się odwrotnie (tak jak ja), ten post może być dla Ciebie.

Nie mogłem zrozumieć, dlaczego moje powiadomienia są usuwane, gdy wyczyściłem odznakę ... Ręcznie zwiększam znaczek, a następnie chcę go wyczyścić, gdy użytkownik wejdzie do aplikacji. Nie ma jednak powodu, aby wyczyścić centrum powiadomień; nadal mogą chcieć zobaczyć te powiadomienia lub podjąć działania na ich podstawie.

Na szczęście minus 1 załatwia sprawę:

[UIApplication sharedApplication].applicationIconBadgeNumber = -1;
TahoeWolverine
źródło
1
Czy to działa dla Ciebie w iOS9? Nie zauważyłem żadnej różnicy w ustawieniu odznaki na 0 lub na -1. Nadal czyści wszystkie zdalne powiadomienia w moim przypadku.
AlexeyVMP,
Tak, znowu zacząłem to zauważać w mojej aplikacji; Nie mam pojęcia, co się zmieniło.
TahoeWolverine
Daję się od firmy Apple jakoś zdecydował, że aplikacja bez numerze szarży nie powinien mieć żadnych powiadomień
AlexeyVMP
1

Może na wypadek, gdyby były zaplanowane alarmy i nie wyczyszczone ikony aplikacji.

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

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

for (UILocalNotification* scheduledLocalNotification in scheduledLocalNotifications) {
    [application scheduleLocalNotification:scheduledLocalNotification];
}
[application setApplicationIconBadgeNumber:applicationIconBadgeNumber];
Park Jong Su
źródło
0

Jeśli w przyszłości będziesz mieć powtarzające się powiadomienia, a nie chcesz anulować tych powiadomień, możesz wyczyścić element w centrum powiadomień, wykonując następujące czynności:

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

Nie możesz wyczyścić powiadomienia, gdy Twoja aplikacja jest otwarta na pierwszym planie, wywołując poniższą metodę natychmiast po otrzymaniu powiadomienia lokalnego, w przeciwnym razie otrzymasz dziesiątki setek powiadomień. Może dlatego, że to samo powiadomienie obowiązuje ponownie, a teraz jest czas na strzelanie, więc kontynuuj ogień, aplikuj ponownie, strzelaj, aplikuj ...

[UIApplication sharedApplication].scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
zgjie
źródło
0

Kiedy wylogowujesz się z aplikacji, w tym momencie musisz użyć poniższego wiersza kodu w metodzie kliknięcia przycisku wylogowania.

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];

[[UIApplication sharedApplication] cancelAllLocalNotifications];

i to działa doskonale w mojej aplikacji.

Vaibhav Shiledar
źródło
0

Musisz dodać poniższy kod w swojej applicationDidBecomeActivemetodzie AppDelegate .

[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
Bhavesh Patel
źródło
-1

Mam to stąd . Działa na 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.
źródło