iOS 10 未收到推送通知,但在 iOS 9 及之前收到推送通知
Push Notifications not being received on iOS 10, but working on iOS 9 and before
我有几个应用程序是用 Swift 2.2 编写的,用 Xcode 7.3 编译并在 App Store 上运行。这些应用程序利用推送通知,在 iOS 9.3 及更早版本中运行良好。
但是,在已升级到 iOS 10 的设备上,我的应用程序没有收到任何推送通知。仍在 运行 iOS 9 的设备仍在接收通知。
认为这可能是证书或授权问题,我尝试了以下操作:
将我的一个应用程序升级到 Swift 2.3,添加了 APS Environment Entitlement 并在 Xcode 8 中编译它,但这没有任何区别。
在我的 AppDelegate 中,我仍然有现有的方法来注册推送通知,包括:
let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories:nil)
application.registerUserNotificationSettings(notificationSettings)
此注册似乎在 iOS 10 上成功,因为随后调用了 Application didRegisterForRemoteNotificationsWithDeviceToken,因此我从 APNS 收到令牌。
问题是当我向此设备发送推送通知时,Application didReceiveRemoteNotification 从未被调用。
现在,here据说 UIApplicationDelegate 上的方法在 iOS10 上被弃用了,我应该实现 userNotificationCenter(:didReceive:withCompletionHandler:) 和 userNotificationCenter(:willPresent:withCompletionHandler:)
问题是我不仅仅针对 iOS 10。我仍然需要应用程序在 iOS 8 和 9 上运行,所以我怀疑这是实现这些方法的正确方法。
如何获取现有应用程序的推送通知以继续在已升级到 iOS 10 的设备上运行?我需要重写代码吗?我是否只需要更新一些证书或权利并使用一些 "new" 设置在 Xcode 8 中重新编译?
IOS10 有不同的通知工具包。
import UserNotifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.badge, .alert , .sound]) { (granted, error) in
if granted {
UIApplication.shared.registerForRemoteNotifications()
}
}
} else {
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
let setting = UIUserNotificationSettings(types: type, categories: nil)
UIApplication.shared.registerUserNotificationSettings(setting)
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
let token = String(format: "%@", deviceToken as CVarArg)
}
好的,我明白了。我现在有我原来的推送通知,它在 iOS 9 上工作,在 iOS 10 上工作,Xcode 8 和 Swift 2.3.
我通过对 AppDelegate 进行以下更改来实现此目的:
1) 在我的项目设置中,在功能选项卡下,我向下滚动到 "Push Notifications" 并将其转到 "ON"。这会自动生成一个包含键 "APS Environment" 和值 "development".
的权利文件
2) 在 AppDelegate.swift 中我做了几处代码更改。我首先导入 UserNotifications 框架:
import UserNotifications
然后我让 AppDelegate 实现 UNUserNotificationCenterDelegate 协议:
class AppDelegate: /*Some other protocols I am extending...*/, UNUserNotificationCenterDelegate {
然后我添加如下方法:
func registerForPushNotifications(application: UIApplication) {
if #available(iOS 10.0, *){
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: {(granted, error) in
if (granted)
{
UIApplication.sharedApplication().registerForRemoteNotifications()
}
else{
//Do stuff if unsuccessful...
}
})
}
else{ //If user is not on iOS 10 use the old methods we've been using
let notificationSettings = UIUserNotificationSettings(
forTypes: [.Badge, .Sound, .Alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
}
}
然后我在 didFinishLaunchingWithOptions:
中调用这个新创建的函数
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
registerForPushNotifications(application)
...
}
我保留我的 didRegisterForRemoteNotificationsWithDeviceToken 方法不变:
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
//Implement this. Do something with the token I receive. Send it to my push notification server to register the device or something else I'd like to do with the token.
}
现在我为 iOS 10 实现了两个新方法来处理推送通知的接收:
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
//Handle the notification
}
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
//Handle the notification
}
我没有删除之前在 iOS 9.
中为推送通知实现的任何方法
在关于 iOS 9 vs iOS 10 推送通知的问题的各种 SO 回复中,我尝试了以下测试:
1) 更新通知调用以专门为 iOS 10 台设备
使用 UNUserNotificationCenter
2) 更新推送功能,以便更新授权文件
我可以确认执行#2 并保持所有现有的 iOS 9 推送代码相同将允许在 iOS 10 设备
上发送基本推送通知
我已经使用以下步骤解决了这个问题:
步骤 1:Go 到项目 -> 目标 -> 功能 -> 推送通知 -> 打开它
第 2 步:修复与正确证书、配置文件相关的问题
第 3 步:退出 Xcode、清理并 运行
当我的应用程序从 IOS 9 移动到 IOS 10 时,应用程序停止接收托管在 Heroku 上的我的 Parse 服务器发送的静默推送通知。
我为使通知再次起作用所做的唯一更改是修改我服务器上的 Javascript,以便 content-available 的参数是一个整数1 而不是字符串“1”
Parse.Push.send({
where: notifyDeletedRequestsQuery,
data: {
'content-available': 1,
refresh: constants.requestsClassName
}
}, { useMasterKey: true });
另请注意,content-available 不能出现在与 徽章、声音或警报相同的推送通知中 。
我有几个应用程序是用 Swift 2.2 编写的,用 Xcode 7.3 编译并在 App Store 上运行。这些应用程序利用推送通知,在 iOS 9.3 及更早版本中运行良好。
但是,在已升级到 iOS 10 的设备上,我的应用程序没有收到任何推送通知。仍在 运行 iOS 9 的设备仍在接收通知。
认为这可能是证书或授权问题,我尝试了以下操作: 将我的一个应用程序升级到 Swift 2.3,添加了 APS Environment Entitlement 并在 Xcode 8 中编译它,但这没有任何区别。
在我的 AppDelegate 中,我仍然有现有的方法来注册推送通知,包括:
let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories:nil)
application.registerUserNotificationSettings(notificationSettings)
此注册似乎在 iOS 10 上成功,因为随后调用了 Application didRegisterForRemoteNotificationsWithDeviceToken,因此我从 APNS 收到令牌。
问题是当我向此设备发送推送通知时,Application didReceiveRemoteNotification 从未被调用。
现在,here据说 UIApplicationDelegate 上的方法在 iOS10 上被弃用了,我应该实现 userNotificationCenter(:didReceive:withCompletionHandler:) 和 userNotificationCenter(:willPresent:withCompletionHandler:)
问题是我不仅仅针对 iOS 10。我仍然需要应用程序在 iOS 8 和 9 上运行,所以我怀疑这是实现这些方法的正确方法。
如何获取现有应用程序的推送通知以继续在已升级到 iOS 10 的设备上运行?我需要重写代码吗?我是否只需要更新一些证书或权利并使用一些 "new" 设置在 Xcode 8 中重新编译?
IOS10 有不同的通知工具包。
import UserNotifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.badge, .alert , .sound]) { (granted, error) in
if granted {
UIApplication.shared.registerForRemoteNotifications()
}
}
} else {
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
let setting = UIUserNotificationSettings(types: type, categories: nil)
UIApplication.shared.registerUserNotificationSettings(setting)
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
let token = String(format: "%@", deviceToken as CVarArg)
}
好的,我明白了。我现在有我原来的推送通知,它在 iOS 9 上工作,在 iOS 10 上工作,Xcode 8 和 Swift 2.3.
我通过对 AppDelegate 进行以下更改来实现此目的:
1) 在我的项目设置中,在功能选项卡下,我向下滚动到 "Push Notifications" 并将其转到 "ON"。这会自动生成一个包含键 "APS Environment" 和值 "development".
的权利文件2) 在 AppDelegate.swift 中我做了几处代码更改。我首先导入 UserNotifications 框架:
import UserNotifications
然后我让 AppDelegate 实现 UNUserNotificationCenterDelegate 协议:
class AppDelegate: /*Some other protocols I am extending...*/, UNUserNotificationCenterDelegate {
然后我添加如下方法:
func registerForPushNotifications(application: UIApplication) {
if #available(iOS 10.0, *){
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: {(granted, error) in
if (granted)
{
UIApplication.sharedApplication().registerForRemoteNotifications()
}
else{
//Do stuff if unsuccessful...
}
})
}
else{ //If user is not on iOS 10 use the old methods we've been using
let notificationSettings = UIUserNotificationSettings(
forTypes: [.Badge, .Sound, .Alert], categories: nil)
application.registerUserNotificationSettings(notificationSettings)
}
}
然后我在 didFinishLaunchingWithOptions:
中调用这个新创建的函数func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
registerForPushNotifications(application)
...
}
我保留我的 didRegisterForRemoteNotificationsWithDeviceToken 方法不变:
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
//Implement this. Do something with the token I receive. Send it to my push notification server to register the device or something else I'd like to do with the token.
}
现在我为 iOS 10 实现了两个新方法来处理推送通知的接收:
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
//Handle the notification
}
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
//Handle the notification
}
我没有删除之前在 iOS 9.
中为推送通知实现的任何方法在关于 iOS 9 vs iOS 10 推送通知的问题的各种 SO 回复中,我尝试了以下测试:
1) 更新通知调用以专门为 iOS 10 台设备
使用 UNUserNotificationCenter2) 更新推送功能,以便更新授权文件
我可以确认执行#2 并保持所有现有的 iOS 9 推送代码相同将允许在 iOS 10 设备
上发送基本推送通知我已经使用以下步骤解决了这个问题:
步骤 1:Go 到项目 -> 目标 -> 功能 -> 推送通知 -> 打开它
第 3 步:退出 Xcode、清理并 运行
当我的应用程序从 IOS 9 移动到 IOS 10 时,应用程序停止接收托管在 Heroku 上的我的 Parse 服务器发送的静默推送通知。
我为使通知再次起作用所做的唯一更改是修改我服务器上的 Javascript,以便 content-available 的参数是一个整数1 而不是字符串“1”
Parse.Push.send({
where: notifyDeletedRequestsQuery,
data: {
'content-available': 1,
refresh: constants.requestsClassName
}
}, { useMasterKey: true });
另请注意,content-available 不能出现在与 徽章、声音或警报相同的推送通知中 。