关于objective C:尝试标记应用程序图标但未获得用户标记应用程序的权限:iOS 8 Xcode 6

Attempting to badge the application icon but haven't received permission from the user to badge the application : iOS 8 Xcode 6

我正在检查我的应用程序与 iOS 8 的兼容性,我得到以下登录控制台"尝试标记应用程序图标但未收到用户授予应用程序标记的权限"。谁能帮我摆脱这个警告。是的,我的应用在应用图标和 TabBar 图标上显示徽章。


这是我在 AppDelegate 中所做的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // registering for remote notifications
    [self registerForRemoteNotification];
    return YES;
}


- (void)registerForRemoteNotification {
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
        UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
    } else {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }
}

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}
#endif


Apple 为注册通知和使用徽章制作了新的 API。

请参阅 WWDC 2014 会议视频:
https://developer.apple.com/videos/wwdc/2014/?id=713 ,
http://asciiwwdc.com/2014/sessions/713(文字版)

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/registerUserNotificationSettings:

用户可以更改设置中每个 UIUserNotificationType (UIUserNotificationTypeBadge, UIUserNotificationTypeSound, UIUserNotificationTypeAlert) 的权限。

在更改徽章之前,您必须检查权限。

来自我的 AppDelegate 的代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (BOOL)checkNotificationType:(UIUserNotificationType)type
{
  UIUserNotificationSettings *currentSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
  return (currentSettings.types & type);
}

- (void)setApplicationBadgeNumber:(NSInteger)badgeNumber
{
  UIApplication *application = [UIApplication sharedApplication];

  if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
    application.applicationIconBadgeNumber = badgeNumber;
  }
  else {
    if ([self checkNotificationType:UIUserNotificationTypeBadge]) {
      NSLog(@"badge number changed to %d", badgeNumber);
      application.applicationIconBadgeNumber = badgeNumber;
    }
    else {
      NSLog(@"access denied for UIUserNotificationTypeBadge");
    }
  }
}

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

UI 应用程序实例中提供了 currentUserNotificationSettings 方法,它将为您提供最新的用户通知首选项。

使用徽章编号:

1
[self setApplicationBadgeNumber:0];

而不是

1
application.applicationIconBadgeNumber = 0;

你可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
        if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])
        {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        } else
        {
            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
             (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
        }
    #else
       [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    #endif

我在 Swift 中寻找解决方案时遇到了这个答案。我已经完成了以下操作(假设 iOS 8):

1
2
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Alert | UIUserNotificationType.Badge, categories: nil))
UIApplication.sharedApplication().registerForRemoteNotifications()


如果您想使用本地通知,请使用以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000


    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
    [[UIApplication sharedApplication] registerForRemoteNotifications];

#else

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
 (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

#endif

我不会检查 IOS 版本,而是检查 UIUserNotificationSettings 是否存在并注册 BadgeType,就像我们过去对远程通知所做的那样。

1
2
3
4
5
6
7
Class userNotification = NSClassFromString(@"UIUserNotificationSettings");

if (userNotification)
{
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}

iOS 8 有一个名为 registerUserNotificationSettings: 的应用程序方法。部分文档说:"如果您的应用在后台显示警报、播放声音或标记其图标,则您必须在启动周期内调用此方法以请求以这些方式提醒用户的权限。"


你可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
if(SYSTEM_VERSION_LESS_THAN(@"8.0"))
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
else
{
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}

....

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

对于推送通知,我认为它会解决它,在我的情况下,在模拟器上我收到此警告,因为它不支持推送并且我用户拒绝许可,而不是再次收到该警告。
谢谢。


你唯一需要的是

1
2
3
4
5
if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_8_0)       {
// here you go with iOS 8
} else {

}

对于"swifters",上面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
final func checkNotificationType(type : UIUserNotificationType) -> Bool {

    let application = UIApplication.sharedApplication()
    if application.respondsToSelector(Selector("registerUserNotificationSettings:")) {
        // iOS8 and above
        let currentSettings : UIUserNotificationSettings = application.currentUserNotificationSettings()
        let types = currentSettings.types
        return types.rawValue & type.rawValue > 0
    }else{
        return true
    }
}

1
2
3
4
5
6
7
8
9
10
+ (BOOL)canBadgeTheApp {
    BOOL canBadgeTheApp;
    if ([UIDevice currentDevice].systemVersion.doubleValue >= 8) {
        UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
        canBadgeTheApp = ((types & UIRemoteNotificationTypeBadge) != 0);
    } else {
        canBadgeTheApp = YES;
    }
    return canBadgeTheApp;
}