objective-c - register - sending push notifications



registerForRemoteNotificationTypes: wird in iOS 8.0 und höher nicht unterstützt (10)

Beim Versuch, sich für Push-Benachrichtigungen unter iOS 8.x zu registrieren:

application.registerForRemoteNotificationTypes(UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound)

Ich erhalte den folgenden Fehler:

registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.

Irgendwelche Ideen, was ist die neue Art, es zu tun? Es funktioniert, wenn ich diese Swift-App auf iOS 7.x ausführe.

BEARBEITEN

Auf iOS 7.x, wenn ich den bedingten Code einbeziehe (entweder SystemVersion-bedingt oder #if __IPHONE_OS_VERSION_MAX_ALLOWED> = 80000)

dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings

Answer #1

Aufbauend auf @ Prasaths Antwort. So machen Sie das in Swift :

if application.respondsToSelector("isRegisteredForRemoteNotifications")
{
    // iOS 8 Notifications
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: (.Badge | .Sound | .Alert), categories: nil));
    application.registerForRemoteNotifications()
}
else
{
    // iOS < 8 Notifications
    application.registerForRemoteNotificationTypes(.Badge | .Sound | .Alert)
}

Answer #2

Das ist eine sauberere Art und Weise und es funktioniert einfach großartig

if (floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_8_0)
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge|
     UIRemoteNotificationTypeAlert| UIRemoteNotificationTypeSound];
     else {
         [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; 
         [application registerForRemoteNotifications];
     }

Answer #3

Für die Swift-Neigung:

if let registration: AnyObject = NSClassFromString("UIUserNotificationSettings") { // iOS 8+
    let notificationTypes: UIUserNotificationType = (.Alert | .Badge | .Sound)
    let notificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)

    application.registerUserNotificationSettings(notificationSettings)
} else { // iOS 7
    application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
}

Answer #4

Für iOS <10

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    //-- Set Notification
    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
    {
           // iOS 8 Notifications
           [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

           [application registerForRemoteNotifications];
    }
    else
    {
          // iOS < 8 Notifications
          [application registerForRemoteNotificationTypes:
                     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }

     //--- your custom code
     return YES;
}

Für iOS10

https://.com/a/39383027/3560390


Answer #5

Ich konnte nicht herausfinden, auf was die "Kategorien" NSSet-Variable eingestellt werden sollte, also wenn jemand mich ausfüllen könnte, werde ich diesen Posten gern bearbeiten. Im Folgenden wird jedoch der Push-Benachrichtigungsdialog angezeigt.

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

Edit: Ich habe eine Push-Benachrichtigung erhalten, die ich mit diesem Code an mein Handy senden kann, daher bin ich mir nicht sicher, ob der categories-Parameter notwendig ist.


Answer #6

Nach Xcode 6.1 Beta funktioniert der folgende Code, geringfügige Bearbeitung von Tom S Code, der nicht mehr mit der Beta 6.1 funktioniert (funktionierte mit vorheriger Beta):

   if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
        // It's iOS 8
        var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
       var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
       UIApplication.sharedApplication().registerUserNotificationSettings(settings)
    } else {
        // It's older
        var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
        UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
    }

Answer #7

Sie können dies verwenden

if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
    {
        // for iOS 8
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

        [application registerForRemoteNotifications];
    }
    else
    {
        // for iOS < 8
        [application registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }

    // RESET THE BADGE COUNT 
    application.applicationIconBadgeNumber = 0;

Answer #8

Wenn Sie Unterstützung für IOS7 IOS8 hinzufügen möchten, können Sie diesen Code in Ihrem Projekt anwenden.

-(void) Subscribe {
    NSLog(@"Registering for push notifications...");

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

-(void)application:(UIApplication *)application 
    didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {

    if (notificationSettings.types) {
        NSLog(@"user allowed notifications");
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        NSLog(@"user did not allow notifications");
        UIAlertView *alert =[[UIAlertView alloc] 
            initWithTitle:@"Please turn on Notification"
            message:@"Go to Settings > Notifications > App.\n Switch on Sound, Badge & Alert"
            delegate:self
            cancelButtonTitle:@"Ok"
            otherButtonTitles: nil];
        [alert show];
        // show alert here
    }
}

Answer #9

Wie Sie beschrieben haben, müssen Sie eine andere Methode verwenden, die auf verschiedenen iOS-Versionen basiert. Wenn Ihr Team sowohl Xcode 5 (das keine iOS 8-Selektoren kennt) als auch Xcode 6 verwendet, müssen Sie das bedingte Kompilieren wie folgt verwenden:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // use registerUserNotificationSettings
} else {
    // use registerForRemoteNotificationTypes:
}
#else
// use registerForRemoteNotificationTypes:
#endif

Wenn Sie nur Xcode 6 verwenden, können Sie genau dies einhalten:

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // use registerUserNotificationSettings
} else {
    // use registerForRemoteNotificationTypes:
}

Der Grund dafür ist, dass sich die Art und Weise, wie Sie Benachrichtigungsberechtigungen erhalten, in iOS 8 geändert hat. Eine UserNotification ist eine Nachricht, die dem Benutzer UserNotification wird, egal ob von Remote oder von lokal. Sie müssen die Erlaubnis erhalten, einen zu zeigen. Dies wird im WWDC 2014 Video "Was ist neu in iOS-Benachrichtigungen" beschrieben


Answer #10

iOS 8 hat die Benachrichtigungsregistrierung nicht rückwärtskompatibel geändert. Während Sie iOS 7 und 8 unterstützen müssen (und während Apps, die mit dem 8 SDK erstellt wurden, nicht akzeptiert werden), können Sie nach den benötigten Selektoren suchen und diese für die laufende Version bedingt korrekt aufrufen.

Hier ist eine Kategorie in UIApplication, die diese Logik hinter einer sauberen Schnittstelle für Sie verbergen wird, die sowohl in Xcode 5 als auch in Xcode 6 funktioniert.

Header:

//Call these from your application code for both iOS 7 and 8
//put this in the public header
@interface UIApplication (RemoteNotifications)

- (BOOL)pushNotificationsEnabled;
- (void)registerForPushNotifications;

@end

Implementierung:

//these declarations are to quiet the compiler when using 7.x SDK
//put this interface in the implementation file of this category, so they are
//not visible to any other code.
@interface NSObject (IOS8)

- (BOOL)isRegisteredForRemoteNotifications;
- (void)registerForRemoteNotifications;

+ (id)settingsForTypes:(NSUInteger)types categories:(NSSet*)categories;
- (void)registerUserNotificationSettings:(id)settings;

@end

@implementation UIApplication (RemoteNotifications)

- (BOOL)pushNotificationsEnabled
{
    if ([self respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
    {
        return [self isRegisteredForRemoteNotifications];
    }
    else
    {
        return ([self enabledRemoteNotificationTypes] & UIRemoteNotificationTypeAlert);
    }
}

- (void)registerForPushNotifications
{
    if ([self respondsToSelector:@selector(registerForRemoteNotifications)])
    {
        [self registerForRemoteNotifications];

        Class uiUserNotificationSettings = NSClassFromString(@"UIUserNotificationSettings");

        //If you want to add other capabilities than just banner alerts, you'll need to grab their declarations from the iOS 8 SDK and define them in the same way.
        NSUInteger UIUserNotificationTypeAlert   = 1 << 2;

        id settings = [uiUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:[NSSet set]];            
        [self registerUserNotificationSettings:settings];

    }
    else
    {
        [self registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
    }
}

@end




apple-push-notifications