Attempting to badge the application icon but haven

2019-01-30 11:11发布

问题:

I am checking my app compatibility with iOS 8, I am getting following Log in console "Attempting to badge the application icon but haven't received permission from the user to badge the application" . Can anyone please help me to get rid of this warning. And Yes, my app shows Badges on App Icon and TabBar Icon.

回答1:

Here is What I did in my AppDelegate

- (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


回答2:

Apple makes new API for registering notifications and working with badges.

See WWDC 2014 session video: https://developer.apple.com/videos/wwdc/2014/?id=713 , http://asciiwwdc.com/2014/sessions/713 (text version) and https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/registerUserNotificationSettings:

User can change permissions for every UIUserNotificationType (UIUserNotificationTypeBadge, UIUserNotificationTypeSound, UIUserNotificationTypeAlert) in Settings.

Before changing badge you must check permissions.

Code sample from my AppDelegate:

- (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)

The currentUserNotificationSettings method is available in the UI application instance and will give you the most up-to-date user notification preferences.

Working with badge number:

[self setApplicationBadgeNumber:0];

instead of

application.applicationIconBadgeNumber = 0;


回答3:

You can use

    #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


回答4:

I came across this answer whilst looking for a solution in Swift. I have done the following (assuming iOS 8):

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


回答5:

Rather than checking the IOS Version i would check if the UIUserNotificationSettings exists and register for BadgeType like we used to do with remote notifications.

Class userNotification = NSClassFromString(@"UIUserNotificationSettings");

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


回答6:

If you want use Local Notification use Below Code:

#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


回答7:

iOS 8 has an application method called registerUserNotificationSettings:. Part of the docs say, "If your app displays alerts, play sounds, or badges its icon while in the background, you must call this method during your launch cycle to request permission to alert the user in those ways."



回答8:

You can use

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)

For push notification, I think it will solve it, in my case on simulator I get this warning as it doesn't support push and i the user reject the permission than again you will have that warning. Thank You.



回答9:

for "swifters" the above code:

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
    }
}


回答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;
}


回答11:

the only thing you need is

if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_8_0)       {
// here you go with iOS 8
} else {

}