ios8 - 在iOS 8.0和更高版本中,不支持registerforremotenotificationtypes

  显示原文与译文双语对照的内容
0 0

在 iOS 8下尝试注册推送通知时:

application.registerForRemoteNotificationTypes(UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound)

出现了以下错误:

registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later.

什么是新的方法? iOS上 7的确能用,当我运行这里 Swift 应用

编辑

在 iOS 7.x 中,当我包含条件代码时得到( SystemVersion条件或者 #if __IPHONE_OS_VERSION_MAX_ALLOWED> = 80000 )

dyld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings
时间:原作者:17个回答

0 0

就像你所描述的,你需要使用基于不同版本的iOS的不同方法。 如果你的团队同时使用了 Xcode 5 ( 它不了解任何 iOS 8选择器) 和 Xcode 6 ( 当前处于测试版中),那么你需要使用条件编译,如下所示:

#if __IPHONE_OS_VERSION_MAX_ALLOWED> = 80000
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
//use registerUserNotificationSettings
} else {
//use registerForRemoteNotificationTypes:
}
#else
//use registerForRemoteNotificationTypes:
#endif

如果你只使用了 Xcode 6 ( 测试版),那么只需遵循以下步骤:

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
//use registerUserNotificationSettings
} else {
//use registerForRemoteNotificationTypes:
}

原因是你在 iOS 8中获得通知权限的方式已经改变。 UserNotification 是显示给用户的消息,无论是来自远程还是来自本地。 你需要获得显示一个权限的权限。 这是在 WWDC 2014视频 "iOS通知中的新增内容"中描述

原作者:
0 0

在 Xcode 6中非常简单( 只在这个版本中工作)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
//-- Set Notification
 if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) 
 {
//iOS 8 Notifications
 [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
 [application registerForRemoteNotifications];
 }
 else
 {
//iOS <8 Notifications
 [application registerForRemoteNotificationTypes:
 (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
 }
//--- your custom code
 return YES;
}
原作者:
0 0

迅速,建筑 @Prasath's 回答。你知道怎么做上 it:

if application.respondsToSelector("isRegisteredForRemoteNotifications")
{
//iOS 8 Notifications
 application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: (.Badge |. Sound |. Alert), categories: nil));
 application.registerForRemoteNotifications()
}
else
{
//iOS <8 Notifications
 application.registerForRemoteNotificationTypes(.Badge |. Sound |. Alert)
}
原作者:
0 0

iOS 8以兼容的方式更改了通知注册。 当你需要支持 iOS 7和 8 ( 当使用 8 SDK构建的应用程序不被接受时) 时,你可以检查所需的选择器并有条件地调用它们来运行运行版本。

下面是UIApplication上的一个类别,它将在一个干净的界面后面隐藏这个逻辑,它可以在 Xcode 5和 Xcode 6中工作。

标题:

//Call these from your application code for both iOS 7 and 8
//put this in the public header
@interface UIApplication (RemoteNotifications)
- (BOOL)pushNotificationsEnabled;
- (void)registerForPushNotifications;
@end

实现:

//these declarations are to quiet the compiler when using 7.x SDK
//put this interface in the implementation file of this category, so they are
//not visible to any other code.
@interface NSObject (IOS8)
- (BOOL)isRegisteredForRemoteNotifications;
- (void)registerForRemoteNotifications;
+ (id)settingsForTypes:(NSUInteger)types categories:(NSSet*)categories;
- (void)registerUserNotificationSettings:(id)settings;
@end
@implementation UIApplication (RemoteNotifications)
- (BOOL)pushNotificationsEnabled
{
 if ([self respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
 {
 return [self isRegisteredForRemoteNotifications];
 }
 else
 {
 return ([self enabledRemoteNotificationTypes] & UIRemoteNotificationTypeAlert);
 }
}
- (void)registerForPushNotifications
{
 if ([self respondsToSelector:@selector(registerForRemoteNotifications)])
 {
 [self registerForRemoteNotifications];
 Class uiUserNotificationSettings = NSClassFromString(@"UIUserNotificationSettings");
//If you want to add other capabilities than just banner alerts, you'll need to grab their declarations from the iOS 8 SDK and define them in the same way.
 NSUInteger UIUserNotificationTypeAlert = 1 <<2;
 id settings = [uiUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:[NSSet set]]; 
 [self registerUserNotificationSettings:settings];
 }
 else
 {
 [self registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
 }
}
@end
原作者:
0 0

对于 Swift-inclined:

if let registration: AnyObject = NSClassFromString("UIUserNotificationSettings") {//iOS 8+
 let notificationTypes: UIUserNotificationType = (.Alert |. Badge |. Sound)
 let notificationSettings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
 application.registerUserNotificationSettings(notificationSettings)
} else {//iOS 7
 application.registerForRemoteNotificationTypes(.Alert |. Badge |. Sound)
}
原作者:
0 0

我认为这是更好的方法来保持向后兼容性如果我们使用这种方法,它是为我的案例工作的,希望能为你工作。 也很容易理解。

if ([[[UIDevice currentDevice] systemVersion] floatValue]> = 8.0)
{
 [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
 [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
 [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
 (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
原作者:
0 0

因此,由于AnyObject是标识的灵魂继承者,你可以在AnyObject上调用任何你想要的消息。 这相当于向id发送消息。 碟 ,这非常正常。但现在我们添加在这个概念中,所有方法都是可选的在 AnyObject,并且我们有一些我们能参与

考虑到上,我希望我可以将 UIApplication.sharedApplication() 转换为 AnyObject,然后创建一个等于方法签名的变量,将该变量设置为可选方法,然后测试变量。 这似乎不起作用。 我的猜测是,当根据网路作业系统 8.0编辑开发工具包,编译器知道从哪里它认为这种方法需要被,所以优化这所有最小化。内存查找。 一切都正常运行,直到我尝试测试变量,此时我得到一个 EXC_BAD_ACCESS 。

然而,在相同的宝石关于WWDC谈话让我找到了我的所有方法都是可选的,它们使用可选的链接来称呼一个可选方法- 而这似乎没有。 蹩脚的部分是,你必须实际尝试调用该方法,以便知道它是否存在,在注册通知的情况下,你会发现这个方法存在问题,因为你在创建一个UIUserNotificationSettings对象。 看起来,使用nil调用这个方法似乎是可行的,所以似乎适合我的解决方案是:

var ao: AnyObject = UIApplication.sharedApplication()
if let x:Void = ao.registerUserNotificationSettings?(nil) {
//It's iOS 8
 var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
 var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
 UIApplication.sharedApplication().registerUserNotificationSettings(settings)
} else {
//It's older
 var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
 UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
}

关于"可选",经过大量的查询协议中的方法在节与这里,在关键点信息来自于这里WWDC相关谈话 https://developer.apple.com/videos/wwdc/2014/#407 右中间

在 Xcode 6.1测试版中,上面的代码不起作用了,下面的代码是有效的:

 if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
//It's iOS 8
 var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
 var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
 UIApplication.sharedApplication().registerUserNotificationSettings(settings)
 } else {
//It's older
 var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
 UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
 }
原作者:
0 0

我不知道"类别"nsset变量应该被设置成什么,所以如果有人可以让我填写,我会乐意编辑这篇文章。 但是,下面会显示推送通知对话框。

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

编辑:我得到了一个推送通知来发送到我的手机,所以我不确定类别参数是必需的。

原作者:
0 0

一个注册为 6.1测试版 Xcode 6.1测试版下列代码的工作方式,那么轻微的汤姆里编辑代码停止 working:

 if UIApplication.sharedApplication().respondsToSelector("registerUserNotificationSettings:") {
//It's iOS 8
 var types = UIUserNotificationType.Badge | UIUserNotificationType.Sound | UIUserNotificationType.Alert
 var settings = UIUserNotificationSettings(forTypes: types, categories: nil)
 UIApplication.sharedApplication().registerUserNotificationSettings(settings)
 } else {
//It's older
 var types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert
 UIApplication.sharedApplication().registerForRemoteNotificationTypes(types)
 }
原作者:
0 0

如果你想添加对 web sphere IOS8的支持,你可以将这里代码应用到你的项目中。

-(void) Subscribe {
 NSLog(@"Registering for push notifications...");
 if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
 UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
 [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
 [[UIApplication sharedApplication] registerForRemoteNotifications];
 } else {
 [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
 }
}
-(void)application:(UIApplication *)application 
 didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
 if (notificationSettings.types) {
 NSLog(@"user allowed notifications");
 [[UIApplication sharedApplication] registerForRemoteNotifications];
 } else {
 NSLog(@"user did not allow notifications");
 UIAlertView *alert =[[UIAlertView alloc] 
 initWithTitle:@"Please turn on Notification"
 message:@"Go to Settings> Notifications> App.n Switch on Sound, Badge & Alert"
 delegate:self
 cancelButtonTitle:@"Ok"
 otherButtonTitles: nil];
 [alert show];
//show alert here
 }
}
原作者:
...