【问题标题】:Attempting to badge the application icon but haven't received permission from the user to badge the application : iOS 8 Xcode 6尝试标记应用程序图标,但未获得用户标记应用程序的权限:iOS 8 Xcode 6
【发布时间】:2014-11-16 09:02:44
【问题描述】:

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

【问题讨论】:

  • 你是在模拟器上用的吗?
  • 不,我正在使用设备测试我的应用程序。
  • @souvickcse 在模拟器上能用吗?

标签: objective-c xcode ios8 badge


【解决方案1】:

你唯一需要的是

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

}

【讨论】:

    【解决方案2】:

    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 的代码示例:

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

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

    使用徽章编号:

    [self setApplicationBadgeNumber:0];
    

    而不是

    application.applicationIconBadgeNumber = 0;
    

    【讨论】:

      【解决方案3】:
      + (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;
      }
      

      【讨论】:

      • Apple 总是说,不要使用#define 或版本来测试功能,使用选择器:responsToSelector.. 如 mikplus 所述。
      【解决方案4】:

      对于“swifters”,上面的代码:

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

      【讨论】:

        【解决方案5】:

        我在 Swift 中寻找解决方案时遇到了这个答案。我做了以下事情(假设 iOS 8):

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

        【讨论】:

        • 对于像我这样的新手,这在didFinishLaunchingWithOptions 函数中的AppDelegate.swift 文件中,并且当应用程序启动时出现的警报消息会询问所有通知类型,即使您删除了一些从那个列表中。
        【解决方案6】:

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

        #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】:

          你可以使用

              #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
          

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

              这是我在 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
              

              【讨论】:

              • 默认情况下不声明SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(...) 宏。我收到警告。你在用这个gist吗?
              • 是的,我使用的是相同的要点。
              • 不需要#ifdef __IPHONE_8_0,因为除非您实际使用的是 ios 8 或更高版本,否则不会调用该委托方法。
              • 也可以使用if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)])来检测是否可以调用iOS 8.0方法
              • NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0 是首选。
              【解决方案10】:

              你可以使用

              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)
              

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

              【讨论】:

                【解决方案11】:

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

                【讨论】:

                • 感谢@Phillip 的快速回复。它也适用于 iOS 6 和 7 吗?还是我们需要对此进行检查?
                • 检查您正在运行的操作系统版本。如果您查看其标题中的方法,它会显示“NS_AVAILABLE_IOS(8_0)”,因此您无法在早期版本中调用它。
                猜你喜欢
                • 2014-11-14
                • 1970-01-01
                • 2017-11-07
                • 1970-01-01
                • 2015-10-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多