请求用户许可在 iOS 8 中接收 UILocalNotifications
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24100313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ask for User Permission to Receive UILocalNotifications in iOS 8
提问by dannysandler
I have set up local notifications in the App Delegate Using this:
我已经在 App Delegate 中设置了本地通知使用这个:
- (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]];
}
When I run the app and then quit it I receive an error saying:
当我运行应用程序然后退出它时,我收到一条错误消息:
2014-06-07 11:14:16.663 CCA-TV[735:149070] Attempting to schedule a local notification{fire date = Saturday, June 7, 2014 at 11:14:21 Pacific Daylight Time, time zone = America/Los_Angeles (PDT) offset -25200 (Daylight), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Saturday, June 7, 2014 at 11:14:21 Pacific Daylight Time, user info = (null)} with an alert but haven't received permission from the user to display alerts
2014-06-07 11:14:16.663 CCA-TV[735:149070]尝试安排本地通知{发布日期 = 2014 年 6 月 7 日星期六 11:14:21 太平洋夏令时,时区 = 美国/洛杉矶(PDT) 偏移量 -25200 (Daylight),重复间隔 = 0,重复计数 = UILocalNotificationInfiniteRepeatCount,下一个触发日期 = 2014 年 6 月 7 日星期六太平洋夏令时间 11:14:21,用户信息 = (null)}并带有警报但尚未获得用户显示警报的许可
How can I get the necessary permission to display the alerts?
如何获得显示警报的必要权限?
回答by Satheeshwaran
Since iOS 8 you need to ask user's permission to show notifications from your app, this applies for both remote/push and local notifications. In Swift you can do it like this,
从 iOS 8 开始,您需要征得用户的许可才能显示来自您的应用程序的通知,这适用于远程/推送和本地通知。在 Swift 中,你可以这样做,
Update for Swift 2.0
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
斯威夫特 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 syntax is also very similar.
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;
}
To check for currently registered notification types you can use UIApplication class's method,
要检查当前注册的通知类型,您可以使用 UIApplication 类的方法,
- (UIUserNotificationSettings *)currentUserNotificationSettings
So if the user has said no to your app then this function should return a setting without any types in it.
所以如果用户对你的应用程序说不,那么这个函数应该返回一个没有任何类型的设置。
I have written a tutorial about this, you could see it here.
我写了一个关于这个的教程,你可以在这里看到。
回答by KPM
Put this code in the view controller where you will first program the notifications (if you program them at launch, then it will be application:didFinishLaunchingWithOptions:
):
将此代码放在视图控制器中,您将首先对通知进行编程(如果您在启动时对其进行编程,那么它将是application:didFinishLaunchingWithOptions:
):
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]];
}
In Swift:
在斯威夫特:
if(UIApplication.instancesRespondToSelector(Selector("registerUserNotificationSettings:"))) {
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Sound, categories: nil))
}
The solutions that test against system version number are sub-optimal and error-prone.
针对系统版本号进行测试的解决方案是次优且容易出错的。
回答by Nagarjun
Try this for Objective-C:
在 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];
}
}
For 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
}
回答by ppalancica
I just faced the same problem. Seems like in iOS 8 we need to do an additional step, usually done inside:
我刚刚面临同样的问题。好像在 iOS 8 中我们需要做一个额外的步骤,通常在里面完成:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /*...*/ }
You can use this code if you want to keep it backward compatible:
如果要保持向后兼容,可以使用此代码:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
#endif
The system will remember the decision, and will only ask once.
系统会记住这个决定,并且只会询问一次。
回答by PSS
**Local Notification with three button action for iOS8+
**iOS8+ 的本地通知三键操作
//Button : I TOOK IT , REMIND LATER , SKIP IT**
//按钮:我接受了,稍后提醒,跳过它**
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()
}
}