Запрашивать разрешение пользователя на получение UILocalNotifications в iOS 8
Я настроил локальные уведомления в делегате приложения, используя это:
- (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]];
}
когда я запускаю приложение, а затем выйти из него я получаю сообщение об ошибке:
2014-06-07 11:14:16.663 CCA-TV[735: 149070] попытка запланировать локальное уведомление {огонь
дата = суббота, 7 июня 2014 в 11: 14: 21 Тихоокеанское летнее время, время
zone = America / Los_Angeles (PDT) смещение -25200 (дневной свет), повтор
интервал = 0, повторов = UILocalNotificationInfiniteRepeatcount,
следующая дата пожара = суббота, 7 июня 2014 в 11: 14: 21 Pacific Daylight
Время, информация о пользователе = (null)} с предупреждением, но не получили
разрешение от пользователя на отображение предупреждений
Как я могу получить необходимое разрешение для отображения предупреждений?
5 ответов:
поскольку iOS 8 вам нужно спросить разрешение пользователя на отображение уведомлений из вашего приложения, это относится как к удаленным/push, так и к локальным уведомлениям. В Swift вы можете сделать это так,
обновление для 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. }синтаксис Objective C также очень похож.
- (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; }для проверки зарегистрированных типов уведомлений вы можете использовать класс UIApplication метод,
- (UIUserNotificationSettings *)currentUserNotificationSettingsпоэтому, если пользователь сказал " Нет " вашему приложению, эта функция должна возвращать настройку без каких-либо типов в ней.
Я написал учебник об этом, вы могли видеть, что он здесь.
поместите этот код в контроллер вида, где вы сначала запрограммируете уведомления (если вы запрограммируете их при запуске, то это будет
application:didFinishLaunchingWithOptions:):if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) { [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]]; }В Swift:
if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))) { UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Sound, categories: nil)) }решения, которые тестируются по номеру версии системы, неоптимальны и подвержены ошибкам.
попробуйте это для 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]; } }Для 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 }
Я только что столкнулся с той же проблемой. Похоже, что в iOS 8 нам нужно сделать дополнительный шаг, обычно выполняемый внутри:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /*...*/ }Вы можете использовать этот код, если вы хотите сохранить обратную совместимость:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) { [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]]; } #endifсистема запомнит решение и спросит только один раз.
* * локальное уведомление с тремя кнопками действия для iOS8+
/ / кнопка: Я взял его, Напомнить позже, пропустить его**
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() } }
Comments