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

我得到的错误是“参数标签”(forType: ,Category:)“不匹配任何可用的重载”

还有别的命令可以让我试试吗?

108507 次浏览

在 iOS10中,而不是在您的代码中,您应该使用以下内容请求通知授权: (不要忘记添加 UserNotifications框架)

if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted: Bool, error: NSError?) in
// Do something here
}
}

另外,正确的代码是(例如,在前一个条件的 else中使用) :

let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared().registerUserNotificationSettings(setting)
UIApplication.shared().registerForRemoteNotifications()

最后,确保 Push Notificationtarget-> Capabilities-> Push notification下被激活(设置为 On)

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(options: [.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 :)
DispatchQueue.main.async {
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
}

导入 UserNotifications框架,然后将 UNUserNotificationCenterDelegate添加到 AppRegiate.swift 中

请求用户许可

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(){ (settings) in


switch settings.soundSetting{
case .enabled:


print("enabled sound setting")


case .disabled:


print("setting has been disabled")


case .notSupported:
print("something vital went wrong here")
}
}

在将 deviceToken Data 对象转换为字符串以便用 Xcode 8的当前测试版发送到我的服务器时,我遇到了问题。特别是在8.0 b6中使用 deviceToken.description 返回“32字节”的那个,它没什么用:)

我就是这么做的。

在 Data 上创建一个扩展来实现一个“ hexString”方法:

extension Data {
func hexString() -> String {
return self.reduce("") { string, byte in
string + String(format: "%02X", byte)
}
}
}

然后,当您从注册远程通知中接收回调时,使用:

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.hexString()
// Send to your server here...
}

来自 返回文章页面的答案是非常简单和有用的。它为我工作,非常感谢。 I just want to poin it out here, so people who need this answer can find it easily. So, here is my code from registering local and remote (push) notification.

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

这对我有用。 第一个应用代理

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

获取设备令牌:

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {


let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})


}
import UserNotifications

接下来,转到目标的项目编辑器,在“常规”选项卡中,查找“链接框架和库”部分。

单击 + 并选择 UserNotifications.Framework:

// iOS 12 support
if #available(iOS 12, *) {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound, .provisional, .providesAppNotificationSettings, .criticalAlert]){ (granted, error) in }
application.registerForRemoteNotifications()
}


// 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])
}

使用 Notification 委托方法

// 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中的特性 你的应用程序。简单的 到项目编辑器为您的目标,然后 单击 能力标签。查找 推送通知并切换 its value to 开始.

请查看下面的链接,以获得更多 Notification 委托方法

处理本地和远程通知 应用程序代理-处理本地和远程通知

Https://developer.apple.com/reference/uikit/uiapplicationdelegate

Simply do the following in didFinishWithLaunching::

if #available(iOS 10.0, *) {


let center = UNUserNotificationCenter.current()


center.delegate = self
center.requestAuthorization(options: []) { _, _ in
application.registerForRemoteNotifications()
}
}

记住导入语句:

import UserNotifications

注意,您应该使用这个操作的主线程。

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
if granted {
DispatchQueue.main.async(execute: {
UIApplication.shared.registerForRemoteNotifications()
})
}
}

First, listen to user notification status, i.e., registerForRemoteNotifications() to get APNs device token;
Second, request authorization. When being authorized by the user, deviceToken will be sent to the listener, the AppDelegate;
第三 ,向服务器报告设备令牌。

extension AppDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// 1. listen(监听) to deviceToken
UIApplication.shared.registerForRemoteNotifications()
// 2. request device token
requestAuthorization()
}


func requestAuthorization() {
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 在系统设置里打开推送,但关掉所有形式的提醒,等价于拒绝推送,得不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 }
// do something
}
}


extension AppDelegate {
func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//
}
    

// 模拟器得不到 token,没配置 aps-certificate 的项目也得不到 token,网络原因也可能导致得不到 token
func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
//
}
}

看看这段注释代码:

import Foundation
import UserNotifications
import ObjectMapper


class AppDelegate{


let center = UNUserNotificationCenter.current()
}


extension AppDelegate {


struct Keys {
static let deviceToken = "deviceToken"
}


// MARK: - UIApplicationDelegate Methods
func application(_: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {


if let tokenData: String = String(data: deviceToken, encoding: String.Encoding.utf8) {
debugPrint("Device Push Token \(tokenData)")
}


// Prepare the Device Token for Registration (remove spaces and < >)
setDeviceToken(deviceToken)
}


func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
debugPrint(error.localizedDescription)
}


// MARK: - Private Methods
/**
Register remote notification to send notifications
*/
func registerRemoteNotification() {


center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in


// Enable or disable features based on authorization.
if granted  == true {


DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
} else {
debugPrint("User denied the permissions")
}
}
}


/**
Deregister remote notification
*/
func deregisterRemoteNotification() {
UIApplication.shared.unregisterForRemoteNotifications()
}


func setDeviceToken(_ token: Data) {
let token = token.map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
UserDefaults.setObject(token as AnyObject?, forKey: “deviceToken”)
}


class func deviceToken() -> String {
let deviceToken: String? = UserDefaults.objectForKey(“deviceToken”) as? String


if isObjectInitialized(deviceToken as AnyObject?) {
return deviceToken!
}


return "123"
}


func isObjectInitialized(_ value: AnyObject?) -> Bool {
guard let _ = value else {
return false
}
return true
}
}


extension AppDelegate: UNUserNotificationCenterDelegate {


func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping(UNNotificationPresentationOptions) -> Swift.Void) {


("\(notification.request.content.userInfo) Identifier: \(notification.request.identifier)")


completionHandler([.alert, .badge, .sound])
}


func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping() -> Swift.Void) {


debugPrint("\(response.notification.request.content.userInfo) Identifier: \(response.notification.request.identifier)")


}
}

如果有什么问题就告诉我!