swift 2:与objective-c相比,推送通知没有委托回调

Posted

技术标签:

【中文标题】swift 2:与objective-c相比,推送通知没有委托回调【英文标题】:swift 2: no delegate callbacks for push notifications as opposed to objective-c 【发布时间】:2016-02-22 13:07:50 【问题描述】:

我创建了 2 个示例(单一视图)项目来测试推送通知,除了通知设置代码之外,我没有添加任何代码,如下所示:

Project1 (Swift 2):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
    UIApplication.sharedApplication().registerUserNotificationSettings(settings)
    UIApplication.sharedApplication().registerForRemoteNotifications()

    return true


func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) 

    print("didRegisterUserNotificationSettings got called")



func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) 

    let trimmedDeviceToken = deviceToken.description .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
        .stringByReplacingOccurrencesOfString(" ", withString: "")
    print("Device Token \(trimmedDeviceToken)")



func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) 
    print("Failed to get token, error: \(error)")

Project2(Objective-C):

 -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 

UIUserNotificationSettings* notificationSettings =
[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert|UIUserNotificationTypeBadge) categories:nil];

[application registerUserNotificationSettings:notificationSettings];
[application registerForRemoteNotifications];

return YES;


  -(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings 

NSLog(@"didRegisterUserNotificationSettings got called");



  -(void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
 

NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""];

NSLog(@"Device Token %@", newToken);
 

   -(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
 
         NSLog(@"Failed to get token, error: %@", error);
 

objective-c 项目在所有测试的设备上都能正常工作:为远程通知注册并在委托回调方法中接收设备令牌,但 swift 项目无法获得任何委托回调s.

在将此问题标记为重复之前阅读我尝试过的内容:

1) AppID 已启用推送通知 2) 推送证书类型是生产,供应配置文件是 AdHoc 生产 3) 两个项目使用相同的 AppID、推送证书和配置文件 4) 这两个项目都在 3 款不同的 iPhone(5、6 和 6Plus)上进行了测试,它们都运行 ios 9.2,每次安装都删除了该应用程序并多次重新启动它们 5) 在 2 台不同的 MAC Pro 机器上使用 Xcode 7.2 构建两个项目 6) 所有 3 部 iPhone 都使用没有防火墙的互联网连接并且所有端口都打开(如 this technical note 中所述),还将 3 台设备上的互联网连接更改为 3G 连接而不是 WIFI。 7) 在项目设置中选中/取消选中推送通知 -> 两个项目的功能(顺便说一下,这一点在我测试时没有效果) 8) 为两个项目尝试了 Xcode Run(顶部按钮)和导出 ipa 包 9) 使用 registerForRemoteNotifications 10) 为两个项目尝试了另一个全新的 AppID、推送证书和配置文件。 11) 删除了两个项目,并用与上面相同的代码创建了另外2个新项目

经过所有这些尝试后,objective-c 项目工作正常,并通过 didRegisterForRemoteNotificationsWithDeviceToken 方法接收设备令牌,但 swift 项目不起作用。

我使用 Apple 的 PersistentConnectionLogging.mobileconfig 配置文件和 uploaded them here 从 iPhone 6Plus 设备生成了 3 个 APN 日志文件(在 apsd_2016_02_24_11_36_29+0300.log 文件中,objective-c 项目的 BundleID 是 XXXXX.push.notification,而 swift 项目的 BundleID 是XXXXX.apnsswift)

【问题讨论】:

【参考方案1】:

原来这个奇怪问题背后的原因是swift的print方法没有在设备的日志中显示输出,而NSLog,swift应用程序没有问题,它只需要使用@987654323 @ 在 Push Notification 委托回调方法中显示消息。

//print("Device Token \(trimmedDeviceToken)")
NSLog("Device Token: %@",trimmedDeviceToken)

【讨论】:

【参考方案2】:

您是否 100% 确定在 Swift 版本中完全调用了 application:didFinishLaunchingWithOptions:?可能是你忘记了,例如在 Swift 版本中设置应用程序委托的名称?要检查,请将一些日志记录代码添加到 Swift application:didFinishLaunchingWithOptions:

另外,确保将 @objc 添加到 Swift 应用委托类(如果还没有的话)并尝试(这是一个很长的尝试)将 dynamic 关键字添加到委托方法。

并尝试将UIApplication.sharedApplication() 替换为application(又一个长镜头)。

【讨论】:

以上是关于swift 2:与objective-c相比,推送通知没有委托回调的主要内容,如果未能解决你的问题,请参考以下文章

Swift和Objective-C混编

Swift和Objective-C混编的注意啦

Swift和Objective-C混编的注意啦

Swift 中的 IBM Silverpop 推送集成

swift 2.2 语法 -第一讲

Swift互用性:与 Objective-C 的 API 交互(Swift 2.0版更新)-备