Debajo de la salida de debugging, debería solicitar permiso de la placa de aplicación

Hice una aplicación muy simple que puede ejecutarse en segundo plano mientras se ejecuta un timer. Si la aplicación todavía está en segundo plano y el timer finaliza, enviará una notificación local y establecerá la insignia de la aplicación en 1. Cuando inicio la aplicación, siempre la borro. Noté que después de instalar Xcode 6 recibía este post cada vez que inicié la aplicación:

"Intentar marcar el ícono de la aplicación pero no ha recibido permiso del usuario para marcar la aplicación"

Es evidente que el text es generado por mi aplicación configurando la insignia en 0 para borrarla. ¿Dónde configuro estos permissions o los solicito? ¿Ahora se considera una notificación push?


El problema se ha solucionado y la respuesta se publica a continuación. La conclusión es que debe get la confirmación del usuario para cualquier tipo de notificación, mientras que eso solía ser cierto solo para las notifications push.

Terminé sin usar la insignia de la aplicación en absoluto y abandoné el fragment de código inicial que he publicado aquí mientras tanto. Como todavía hay personas leyendo y comentando esta pregunta, agregaré aquí también mi solución actual de trabajo. Contiene cheques para iOS7 pero no uso el método de callback. Además, esta versión ya no solo solicita el permiso de Badge de aplicación.

Solución

UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; [[UIApplication shanetworkingApplication] registerUserNotificationSettings:notificationSettings]; 

Esto es lo que uso ahora

file .h

 #import <Foundation/Foundation.h> @interface NotificationPermissionHandler : NSObject + (void)checkPermissions; + (bool)canSendNotifications; @end 

Archivo .m:

 #import "NotificationPermissionHandler.h" @implementation NotificationPermissionHandler static const UIUserNotificationType USER_NOTIFICATION_TYPES_REQUIRED = UIUserNotificationTypeAlert | UIUserNotificationTypeSound; static const UIRemoteNotificationType REMOTE_NOTIFICATION_TYPES_REQUIRED = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound; + (void)checkPermissions; { bool isIOS8OrGreater = [[UIApplication shanetworkingApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]; if (!isIOS8OrGreater) { [NotificationPermissionHandler iOS7AndBelowPermissions]; return; } [NotificationPermissionHandler iOS8AndAbovePermissions]; } + (void)iOS7AndBelowPermissions { [[UIApplication shanetworkingApplication] registerForRemoteNotificationTypes:REMOTE_NOTIFICATION_TYPES_REQUIRED]; } + (void)iOS8AndAbovePermissions; { if ([NotificationPermissionHandler canSendNotifications]) { return; } UIUserNotificationSettings* requestedSettings = [UIUserNotificationSettings settingsForTypes:USER_NOTIFICATION_TYPES_REQUIRED categories:nil]; [[UIApplication shanetworkingApplication] registerUserNotificationSettings:requestedSettings]; } + (bool)canSendNotifications; { UIApplication *application = [UIApplication shanetworkingApplication]; bool isIOS8OrGreater = [application respondsToSelector:@selector(currentUserNotificationSettings)]; if (!isIOS8OrGreater) { // We actually just don't know if we can, no way to tell programmatically before iOS8 return true; } UIUserNotificationSettings* notificationSettings = [application currentUserNotificationSettings]; bool canSendNotifications = notificationSettings.types == USER_NOTIFICATION_TYPES_REQUIRED; return canSendNotifications; } @end 

Esta fue mi primera solucion

Lo guardé solo como reference para la discusión inicial. Este código no se mantiene.

 UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge]; [[UIApplication shanetworkingApplication] registerUserNotificationSettings:notificationSettings]; 

También puede acumular permissions en una request haciendo esto:

 UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [[UIApplication shanetworkingApplication] registerUserNotificationSettings:notificationSettings]; 

También desde iOS 8 es posible determinar qué tipo de alertas está permitido por el usuario:

 UIUserNotificationSettings* notificationSettings = [[UIApplication shanetworkingApplication] currentUserNotificationSettings]; if (notificationSettings.types == UIUserNotificationTypeBadge) { // change the badge } 

Terminé usando este código:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (![defaults objectForKey:@"first_run"]) { [self setDefaults]; } [self askAlertPermissions]; if ([self canChangeBadge]) { [self setBadge:0]; } return YES; } - (void)setDefaults; { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[NSNumber numberWithBool:NO] forKey:@"alerts_allowed"]; [defaults setObject:[NSDate date] forKey:@"first_run"]; // More defaults if needed [defaults synchronize]; } - (void)askAlertPermissions; { UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [[UIApplication shanetworkingApplication] registerUserNotificationSettings:notificationSettings]; } // This will be called only after confirming your settings - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings; { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // There is also a built in method to find out if the user has appropriate settings, you might want to use that instead if you just want to know what the setting is [defaults setObject:[NSNumber numberWithBool:YES] forKey:@"alerts_allowed"]; } - (bool)canChangeBadge; { UIUserNotificationSettings* notificationSettings = [[UIApplication shanetworkingApplication] currentUserNotificationSettings]; return notificationSettings.types == UIUserNotificationTypeBadge; } 

Más para leer:

https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html

https://developer.apple.com/documentation/uikit/uiapplication