xcode 调试输出提到我应该请求应用程序徽章权限
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24028172/
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
Debug output mentions I should ask for Application Badge permission
提问by Departamento B
I made a very simple app that can run in the background while a timer runs. If the app is still in the background and the timer ends it will send a local notification and set the application badge to 1. When I start the app I always clear it. I noticed that after installing Xcode 6 I was getting this message every time I started the app:
我制作了一个非常简单的应用程序,它可以在计时器运行时在后台运行。如果应用程序仍在后台并且计时器结束,它将发送本地通知并将应用程序标志设置为 1。当我启动应用程序时,我总是清除它。我注意到安装 Xcode 6 后,每次启动应用程序时都会收到此消息:
"Attempting to badge the application icon but haven't received permission from the user to badge the application"
“尝试标记应用程序图标,但尚未获得用户标记应用程序的许可”
Clearly that text is generated by my app setting the badge to 0 to clear it. Where do I set these permissions or request them? Is it now regarded as a push notification?
显然,该文本是由我的应用程序生成的,将徽章设置为 0 以清除它。我在哪里设置这些权限或请求它们?现在算是推送通知吗?
The problem has been fixed and the answer is posted below. The bottom line is that you need to get confirmation from the user for any kind of notification, while that used to be true only for push notifications.
问题已解决,答案已发布在下面。最重要的是,对于任何类型的通知,您都需要获得用户的确认,而过去仅适用于推送通知。
回答by Departamento B
I ended up not using the Application Badge at all and I abandoned the initial code snippet that I have posted here in the mean while. Since there are still people reading and commenting on this question I will add my working current solution here as well. It does contains checks for iOS7 but I do not use the callback method. Also this version doesn't just ask for Application Badge permission anymore.
我最终根本没有使用应用程序徽章,同时我放弃了我在这里发布的初始代码片段。由于仍然有人在阅读和评论这个问题,因此我也将在这里添加我的当前工作解决方案。它确实包含对 iOS7 的检查,但我不使用回调方法。此外,此版本不再仅要求应用程序徽章许可。
Solution
解决方案
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
This is what I use now
这是我现在使用的
.h file
.h 文件
#import <Foundation/Foundation.h>
@interface NotificationPermissionHandler : NSObject
+ (void)checkPermissions;
+ (bool)canSendNotifications;
@end
.m file:
.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 sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)];
if (!isIOS8OrGreater)
{
[NotificationPermissionHandler iOS7AndBelowPermissions];
return;
}
[NotificationPermissionHandler iOS8AndAbovePermissions];
}
+ (void)iOS7AndBelowPermissions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:REMOTE_NOTIFICATION_TYPES_REQUIRED];
}
+ (void)iOS8AndAbovePermissions;
{
if ([NotificationPermissionHandler canSendNotifications])
{
return;
}
UIUserNotificationSettings* requestedSettings = [UIUserNotificationSettings settingsForTypes:USER_NOTIFICATION_TYPES_REQUIRED categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:requestedSettings];
}
+ (bool)canSendNotifications;
{
UIApplication *application = [UIApplication sharedApplication];
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
This was my first solution
这是我的第一个解决方案
I kept it just as a reference for to the initial discussion. This code is not maintained.
我保留它作为初始讨论的参考。不维护此代码。
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
You can also stack permissions into one request by doing this:
您还可以通过执行以下操作将权限堆叠到一个请求中:
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
Also since iOS 8 it's possible to figure out what kind of alerts are allowed by the user:
此外,从 iOS 8 开始,可以确定用户允许什么样的警报:
UIUserNotificationSettings* notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (notificationSettings.types == UIUserNotificationTypeBadge)
{
// change the badge
}
I ended up using this code:
我最终使用了这个代码:
- (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 sharedApplication] 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 sharedApplication] currentUserNotificationSettings];
return notificationSettings.types == UIUserNotificationTypeBadge;
}
More to read:
更多阅读:
https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html
https://developer.apple.com/documentation/uikit/uiapplication
https://developer.apple.com/documentation/uikit/uiapplication