RegisterForRemoteNotificationTypes: no es compatible con iOS 8.0 y posteriores
Al intentar registrarse para recibir notificaciones automáticas en iOS 8.x:
application.registerForRemoteNotificationTypes(UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound)
Obtuve el siguiente error:
registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.
¿Alguna idea de cuál es la nueva forma de hacerlo? Funciona cuando ejecuto esta aplicación Swift en iOS 7.x.
EDITAR
En iOS 7.x, cuando incluyo el código condicional, obtengo (ya sea SystemVersion condicional o #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings
Para 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;
}
Para iOS10
https://stackoverflow.com/a/39383027/3560390
Como describió, deberá utilizar un método diferente según las diferentes versiones de iOS. Si su equipo usa Xcode 5 (que no conoce ningún selector de iOS 8) y Xcode 6, necesitará usar la compilación condicional de la siguiente manera:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// use registerUserNotificationSettings
} else {
// use registerForRemoteNotificationTypes:
}
#else
// use registerForRemoteNotificationTypes:
#endif
Si solo estás usando Xcode 6, puedes quedarte con esto:
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// use registerUserNotificationSettings
} else {
// use registerForRemoteNotificationTypes:
}
La razón aquí es que la forma de obtener permisos de notificación ha cambiado en iOS 8. A UserNotification
es un mensaje que se muestra al usuario, ya sea de forma remota o local. Necesita obtener permiso para mostrar uno. Esto se describe en el vídeo de la WWDC 2014 "Novedades de las notificaciones de iOS".
Aprovechando la respuesta de @Prasath. Así es como se hace en 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)
}
iOS 8 ha cambiado el registro de notificaciones de una manera no compatible con versiones anteriores. Si bien necesita ser compatible con iOS 7 y 8 (y aunque no se aceptan aplicaciones creadas con el SDK 8), puede verificar los selectores que necesita y llamarlos condicionalmente correctamente para la versión en ejecución.
Aquí hay una categoría en UIApplication que ocultará esta lógica detrás de una interfaz limpia que funcionará tanto en Xcode 5 como en Xcode 6.
Encabezamiento:
//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
Implementación:
//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