permitir - Solicitar permiso de usuario para recibir UILocalNotifications en iOS 8
como permitir fuentes desconocidas en iphone (5)
Configuré las notificaciones locales en el delegado de la aplicación usando esto:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UILocalNotification *notification = [[UILocalNotification alloc]init];
[notification setAlertBody:@"Watch the Latest Episode of CCA-TV"];
[notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:5]];
[notification setTimeZone:[NSTimeZone defaultTimeZone]];
[application setScheduledLocalNotifications:[NSArray arrayWithObject:notification]];
}
Cuando ejecuto la aplicación y luego la dejo, recibo un error que dice:
2014-06-07 11: 14: 16.663 CCA-TV [735: 149070] Intentando programar una notificación local {fecha de activación = sábado, 7 de junio de 2014 a las 11:14:21 Hora del Pacífico, zona horaria = América / Los_Angeles (PDT) offset -25200 (Daylight), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = sábado, 7 de junio de 2014 a las 11:14:21 Pacific Daylight Time, user info = (null)} con una alerta pero no han recibido permiso del usuario para mostrar alertas
¿Cómo puedo obtener el permiso necesario para mostrar las alertas?
** Notificación local con acción de tres botones para iOS8 +
// Botón: LO TOMÉ, RECUERDE MÁS TARDE, PASE **
let completeAction = UIMutableUserNotificationAction()
completeAction.identifier = "COMPLETE_TODO"
completeAction.title = "I TOOK IT"
completeAction.activationMode = .Background
completeAction.destructive = true
completeAction.authenticationRequired = false
let remindAction = UIMutableUserNotificationAction()
remindAction.identifier = "REMIND_TODO"
remindAction.title = "REMIND LATER"
remindAction.activationMode = .Background
remindAction.destructive = false
// remindAction.authenticationRequired = false
let skipAction = UIMutableUserNotificationAction()
skipAction.identifier = "SKIP_TODO"
skipAction.title = "SKIP IT"
skipAction.activationMode = .Background
skipAction.destructive = false
skipAction.authenticationRequired = false
let todoCategory = UIMutableUserNotificationCategory()
todoCategory.identifier = "TODO_CATEGORY"
todoCategory.setActions([completeAction, remindAction, skipAction], forContext: .Default)
todoCategory.setActions([completeAction,remindAction,skipAction], forContext: .Minimal)
if application.respondsToSelector("isRegisteredForRemoteNotifications")
{
let categories = NSSet(array: [todoCategory,todoVideoCategory])
let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: categories as? Set<UIUserNotificationCategory>)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
}
Acabo de enfrentar el mismo problema. Parece que en iOS 8 tenemos que hacer un paso adicional, generalmente dentro de:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /*...*/ }
Puede usar este código si desea mantenerlo compatible con versiones anteriores:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
#endif
El sistema recordará la decisión y solo preguntará una vez.
Desde iOS 8, debes pedirle permiso al usuario para que muestre notificaciones desde tu aplicación, esto se aplica tanto a las notificaciones remotas / push como a las locales. En Swift puedes hacerlo así,
Actualización para Swift 2.0
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
// Override point for customization after application launch.
if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:")))
{
let notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "INVITE_CATEGORY"
notificationCategory.setActions([replyAction], forContext: UIUserNotificationActionContext.Default)
//registerting for the notification.
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes:[.Sound, .Alert, .Badge], categories: nil))
}
else
{
//do iOS 7 stuff, which is pretty much nothing for local notifications.
}
return true
}
Swift 3.2
if(UIApplication.instancesRespond(to: #selector(UIApplication.registerUserNotificationSettings(_:)))){
let notificationCategory:UIMutableUserNotificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "INVITE_CATEGORY"
notificationCategory.setActions([replyAction], forContext: UIUserNotificationActionContext.Default)
//registerting for the notification.
application.registerUserNotificationSettings(UIUserNotificationSettings(types:[.sound, .alert, .badge], categories: nil))
}
else{
//do iOS 7 stuff, which is pretty much nothing for local notifications.
}
La sintaxis de Objective C también es muy similar.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
// Override point for customization after application launch.
return YES;
}
Para verificar los tipos de notificación actualmente registrados, puede usar el método de la clase UIApplication,
- (UIUserNotificationSettings *)currentUserNotificationSettings
Por lo tanto, si el usuario ha dicho que no a su aplicación, esta función debe devolver una configuración sin ningún tipo.
He escrito un tutorial sobre esto, puedes verlo here .
Ponga este código en el controlador de vista donde primero programará las notificaciones (si las programa en el lanzamiento, entonces será la application:didFinishLaunchingWithOptions:
:
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]];
}
En Swift:
if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))) {
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Sound, categories: nil))
}
Las soluciones que prueban el número de versión del sistema son subóptimas y propensas a errores.
Pruebe esto con Objective-C:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// are you running on iOS8?
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else // iOS 7 or earlier
{
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
}
Para Swift:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
// Override point for customization after application launch.
if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:")))
{
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Alert | UIUserNotificationType.Badge, categories: nil))
}
else
{
//
}
return true
}