Remote-Benachrichtigung iOS 8

76

Wie kann ich das Geräte-Token für die Remote-Benachrichtigung in iOS 8 erhalten? Ich habe die Methode didRegisterForRemoteNotificationsWithDeviceTokenin AppDelegateiOS <8 verwendet und das Gerätetoken zurückgegeben. In iOS 8 ist dies jedoch nicht der Fall.

quang thang
quelle
Das hat wirklich funktioniert ..! stackoverflow.com/questions/4086599/…

Antworten:

180

Lesen Sie den Code in UIApplication.h.

Sie werden wissen, wie das geht.

Zuerst:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Code wie folgt hinzufügen

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
#ifdef __IPHONE_8_0
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert 
      | UIUserNotificationTypeBadge 
      | UIUserNotificationTypeSound) categories:nil];
  [application registerUserNotificationSettings:settings];
#endif
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

Wenn Sie nicht sowohl Xcode 5 als auch Xcode 6 verwenden , versuchen Sie diesen Code

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
      |UIRemoteNotificationTypeSound
      |UIRemoteNotificationTypeAlert) categories:nil];
  [application registerUserNotificationSettings:settings];
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}

(Danke für die Erinnerung an @zeiteisen @dmur)


Zweite:

Fügen Sie diese Funktion hinzu

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}
#endif

Und Sie können das deviceToken in bekommen

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

Wenn es immer noch nicht funktioniert, verwenden Sie diese Funktion und melden Sie den Fehler

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
Madao
quelle
4
Diese. Sophomorischerweise konnte Apple die Dokumentation für iOS 8 nicht aktualisieren UIUserNotificationSettingsoder darüber UIApplicationsprechen, wie dies für iOS 8 erforderlich ist. Sie ist stattdessen in den API-Unterschieden vergraben.
Hyperbole
27
Dies stürzt bei iOS-Versionen unter iOS 8 ab. #IFdef ist eine COMPILER-Funktion und wird zur Kompilierungszeit ausgewertet. Sie benötigen noch eine Laufzeitprüfung!
Dan VanWinkle
4
Verwenden Sie dieses Makro, um nach iOS 8 zu suchen: #define isAtLeastiOS8 ([[[UIDevice currentDevice] systemVersion] floatValue]> = 8.0). __IPHONE_8_0 ist keine gute Prüfung, da dieser Code auch in zukünftigen Versionen weiterhin ausgeführt werden soll.
er0
2
In diesem Fall ist das #ifdef jedoch nicht erforderlich, es sei denn, Ihr Team verwendet sowohl Xcode 5 als auch Xcode 6. Stattdessen sollten Sie eine if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {Überprüfung durchführen, wie dies zeiteisen in seiner Antwort tut.
dmur
6
Kleine Bitkorrektur für veraltete Aufzählung UIRemoteNotificationType: NS_ENUM_DEPRECATED_IOS (3_0, 8_0, "Verwenden Sie UIUserNotificationType für Benutzerbenachrichtigungen und registerForRemoteNotifications zum Empfangen von Remotebenachrichtigungen."); Daher müssen Sie für iOS 8 und höher UIUserNotificationTypeBadge, UIUserNotificationTypeSound und UIUserNotificationTypeAlert verwenden. (UIUserNotificationType für neue Versionen, UIRemoteNotificationType - für ältere). Aufzählungen definiert in <UIKit / UIApplication.h> und <UIKit / UIUserNotificationSettings.h>
KepPM
75

Die Möglichkeit, sich für iOS 8 zu registrieren und weiterhin ältere Versionen zu unterstützen

UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
                                                                                         |UIUserNotificationTypeSound
                                                                                         |UIUserNotificationTypeAlert) categories:nil];
    [application registerUserNotificationSettings:settings];
} else {
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [application registerForRemoteNotificationTypes:myTypes];
}

und im App-Delegaten hinzufügen

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

iOS8 kann stille Benachrichtigungen empfangen, ohne um Erlaubnis zu bitten. Anruf - (void)registerForRemoteNotifications . Danach application:didRegisterForRemoteNotificationsWithDeviceToken:wird aufgerufen

Hinweis: Der Rückruf mit dem Token wird nur aufgerufen, wenn sich die Anwendung mit der folgenden Funktion erfolgreich für Benutzerbenachrichtigungen registriert hat oder wenn die Aktualisierung der Hintergrund-App aktiviert ist.

Überprüfen Sie die Einstellungen für Ihre App, wenn ein Benachrichtigungstyp aktiviert ist. Wenn nicht, erhalten Sie kein Geräte-Token.

Sie können jetzt stille Benachrichtigungen mit erhalten

aps {
content-available: 1
}

in der Benachrichtigungsnutzlast

Benachrichtigungen, die angezeigt werden, müssen jedoch noch genehmigt werden. Anruf

UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:notificationSettings];

Dieser Code sollte um Erlaubnis bitten.

Sie sollten jetzt bereit sein, Push-Benachrichtigungen zu erhalten

zeiteisen
quelle
1
Danke für das OS8 can receive silent notifications without asking for permissionbisschen. Das hat mich verrückt gemacht und dies ist der einzige Ort, an dem ich dieses hilfreiche Stück gefunden habe!
sbauch
@zeiteisen, in Ihrer ersten ifAussage sollten Sie UIUserNotificationTypeSoundanstelle von verwenden UIRemoteNotificationTypeSound, da UIRemoteNotificationTypein iOS 8 veraltet ist.
Tanner Semerad
Kann jemand erklären, warum der Rückruf mit dem Token nur aufgerufen wird, wenn die Aktualisierung der Hintergrund-App aktiviert ist? Ich
denke,
15

In meinem Fall hatte ich die erforderlichen Aktualisierungen vorgenommen, um den Push-Benachrichtigungszugriff für iOS 7 und iOS 8 anzufordern. Ich hatte den neuen Rückruf jedoch nicht implementiert, wenn ein iOS 8-Benutzer Zugriff gewährt. Ich musste diese Methode meinem App-Delegaten hinzufügen.

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}
Kyle Clegg
quelle
1

Wenn Sie Xamarin.iOS zum Erstellen Ihrer mobilen Anwendung verwenden, können Sie diesen Codeausschnitt verwenden, um die Registrierung von Push-Benachrichtigungen anzufordern

if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
{
    UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
    UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
    UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
else
{
    UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
} 

Außerdem müssen Sie die DidRegisterUserNotificationSettingsMethode überschreiben , damit das Gerätetoken vom APNS-Server zurückgegeben wird:

public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings)
{
    application.RegisterForRemoteNotifications();
}
Michael Kniskern
quelle
1

Die Antwort von Madao ( https://stackoverflow.com/a/24488562/859742 ) ist richtig, aber ....

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge

sollte "korrekter" sein

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];

Diese Flags haben die gleichen Bitmaskenwerte, weshalb beide funktionieren würden, dies jedoch nicht UIUserNotificationSettingserfordern .UIUserNotificationTypeUIRemoteNotificationType

Ansonsten würde ich anrufen

[application registerUserNotificationSettings:settings];

In der AppDelegateMethode (abhängig von den gewährten Rechten),

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
Ilker Baltaci
quelle
Was ist der Unterschied?
Vladimir Stazhilov
1
UIUserNotificationTypeBadge und UIRemoteNotificationTypeBadge sind gleiche Bitmasken, bedeuten aber unterschiedliche Dinge =)
Ilker Baltaci
0

Ich denke, der bessere Weg, um die Abwärtskompatibilität aufrechtzuerhalten, können wir mit diesem Ansatz verfolgen. Er funktioniert für meinen Fall und hofft, dass er für Sie funktioniert. Auch ziemlich leicht zu verstehen.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }
Hussain KMR Behestee
quelle
0
UIUserNotificationType types = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

    UIUserNotificationSettings *mySettings =
    [UIUserNotificationSettings settingsForTypes:types categories:nil];

    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

    [application registerForRemoteNotifications];
Devang Tandel
quelle