在Xcode 8 / Swift 3.0中注册推送通知?
我试图让我的应用程序在Xcode 8.0中工作,并且遇到错误。 我知道这个代码在以前版本的swift中工作得很好,但我假设在新版本中更改了代码。 这是我试图运行的代码:
let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil) UIApplication.sharedApplication().registerUserNotificationSettings(settings) UIApplication.shared().registerForRemoteNotifications()
我得到的错误是“参数标签”(forTypes :,类别:)“不匹配任何可用的重载”
有没有不同的命令,我可以尝试得到这个工作?
导入
UserNotifications
框架并在AppDelegate.swift中添加UNUserNotificationCenterDelegate
请求用户权限
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in // Enable or disable features based on authorization. } application.registerForRemoteNotifications() return true }
获取设备令牌
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print(deviceTokenString) }
在出错的情况下
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("i am not available in simulator \(error)") }
如果你需要知道授予的权限
UNUserNotificationCenter.current().getNotificationSettings(){ (setttings) in switch setttings.soundSetting{ case .enabled: print("enabled sound setting") case .disabled: print("setting has been disabled") case .notSupported: print("something vital went wrong here") } }
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { if #available(iOS 10, *) { //Notifications get posted to the function (delegate): func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)" UNUserNotificationCenter.current().requestAuthorization([.alert, .badge, .sound]) { (granted, error) in guard error == nil else { //Display Error.. Handle Error.. etc.. return } if granted { //Do stuff here.. //Register for RemoteNotifications. Your Remote Notifications can display alerts now :) application.registerForRemoteNotifications() } else { //Handle user denying permissions.. } } //Register for remote notifications.. If permission above is NOT granted, all notifications are delivered silently to AppDelegate. application.registerForRemoteNotifications() } else { let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) application.registerUserNotificationSettings(settings) application.registerForRemoteNotifications() } return true }
我在回答这里的问题时将deviceToken Data对象转换为一个string发送到我的服务器与Xcode 8的当前testing版。尤其是那个正在使用deviceboken.description 8.0b6,将返回“32字节”其中不是很有用:)
这是为我工作…
在Data上创build一个扩展来实现“hexString”方法:
extension Data { func hexString() -> String { return self.reduce("") { string, byte in string + String(format: "%02X", byte) } } }
然后当你从注册远程通知收到callback时使用它:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.hexString() // Send to your server here... }
在iOS10而不是你的代码中,你应该通过以下方式请求一个通知的授权:(不要忘记添加UserNotifications
Framework)
if #available(iOS 10.0, *) { UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted: Bool, error: NSError?) in // Do something here } }
此外,正确的代码是(例如在以前的条件中使用):
let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) UIApplication.shared().registerUserNotificationSettings(setting) UIApplication.shared().registerForRemoteNotifications()
最后,确保在target
– > Capabilities
– > Push notification
下激活Push notification
。 (将其设置为On
)
import UserNotifications
接下来,转到您的目标的项目编辑器,然后在常规选项卡中查找链接的框架和库部分。
点击+并selectUserNotifications.framework:
// iOS 10 support if #available(iOS 10, *) { UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in } application.registerForRemoteNotifications() } // iOS 9 support else if #available(iOS 9, *) { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } // iOS 8 support else if #available(iOS 8, *) { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } // iOS 7 support else { application.registerForRemoteNotifications(matching: [.badge, .sound, .alert]) }
使用通知委托方法
// Called when APNs has assigned the device a unique token func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // Convert token to string let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print("APNs device token: \(deviceTokenString)") } // Called when APNs failed to register the device for push notifications func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { // Print the error to console (you should alert the user that registration failed) print("APNs registration failed: \(error)") }
用于接收推送通知
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { completionHandler(UIBackgroundFetchResult.noData) }
设置推送通知将启用Xcode 8中的function为您的应用程序。 只需转到目标项目编辑器 ,然后单击function选项卡 。 查找推送通知并将其值切换为开 。
请查看下面的链接了解更多通知委托方法
处理本地和远程通知UIApplicationDelegate – 处理本地和远程通知
https://developer.apple.com/reference/uikit/uiapplicationdelegate
那么这个工作对我来说。 首先在AppDelegate
import UserNotifications
然后:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. registerForRemoteNotification() return true } func registerForRemoteNotification() { if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in if error == nil{ UIApplication.shared.registerForRemoteNotifications() } } } else { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } }
获得devicetoken:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) }
开头,你应该使用这个动作的主线程。
let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in if granted { DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() }) } }
只需在didFinishWithLaunching:
执行以下操作::
if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: []) { _, _ in application.registerForRemoteNotifications() } }
记住导入语句:
import UserNotifications
ast1的答案非常简单而有用。 它适合我,非常感谢你。 我只是想在这里指出,所以需要这个答案的人可以很容易地find它。 所以,这里是我的代码注册本地和远程(推)通知。
//1. In Appdelegate: didFinishLaunchingWithOptions add these line of codes let mynotif = UNUserNotificationCenter.current() mynotif.requestAuthorization(options: [.alert, .sound, .badge]) {(granted, error) in }//register and ask user's permission for local notification //2. Add these functions at the bottom of your AppDelegate before the last "}" func application(_ application: UIApplication, didRegister notificationSettings: UNNotificationSettings) { application.registerForRemoteNotifications()//register for push notif after users granted their permission for showing notification } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print("Device Token: \(tokenString)")//print device token in debugger console } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register: \(error)")//print error in debugger console }
一 ,请求授权;
其次 ,在被用户授权时, registerForRemoteNotifications()
获取APNs设备令牌;
第三 ,将设备令牌报告给您的服务器。
extension AppDelegate { /// 向操作系统索要推送权限(并获取推送 token) static func registerRemoteNotifications() { if #available(iOS 10, *) { let uc = UNUserNotificationCenter.current() uc.delegate = UIApplication.shared.delegate as? AppDelegate uc.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if let error = error { // 无论是拒绝推送,还是不提供 aps-certificate,此 error 始终为 nil print("UNUserNotificationCenter 注册通知失败, \(error)") } DispatchQueue.main.async { onAuthorization(granted: granted) } } } else { let app = UIApplication.shared app.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) // 获取用户授权} } // 在 app.registerUserNotificationSettings() 之后收到用户接受或拒绝及默拒后,此委托方法被调用func application(_ app: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) { // 已申请推送权限,所作的检测才有效// a 征询推送许可时,用户把app切到后台,就等价于默拒了推送// b 在系统设置里打开推送,但关掉所有forms的提醒,等价于拒绝推送,得不token,也收不推送// c 关掉badge, alert和sound 时,notificationSettings.types.rawValue 等于 0 和 app.isRegisteredForRemoteNotifications 成立,但能得到token,也能收到推送(锁屏和通知中心也能看到推送),这说明types涵盖并不全面// 对于模拟器来说,由于不能接收推送,所以 isRegisteredForRemoteNotifications 始终为 false onAuthorization(granted: app.isRegisteredForRemoteNotifications) } static func onAuthorization(granted: Bool) { guard granted else { return } UIApplication.shared.registerForRemoteNotifications() // 获取 deviceToken } } extension AppDelegate { func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // } // 模拟器得不到 token,没configuration aps-certificate 的项目也得不到 token,networking原因也可能导致得不到 token func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { // } }
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let notificationCenter = UNUserNotificationCenter.current() notificationCenter.requestAuthorization([.alert , .sound]) { (finished, err) in if err == nil { application.registerForRemoteNotifications() } } return true }