iOS10推送通知(本地&遠程)

一.發(fā)送一個簡單的本地通知

1.注冊通知

  • 需要導入頭文件或者框架UserNotifications

  • 在iOS8.0之后,如果想要用戶接收通知需要主動請求授權,為了能讓該代碼一定被執(zhí)行,一般寫在Appdelegate中


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

// 1.獲取通知中心

let center = UNUserNotificationCenter.current()

// 2.注冊通知(會彈框請求用戶授權)

// 如果有錯誤則直接返回

if error != nil {

return

}

// 授權成功則為true

if granted {

print("用戶同意通知")

} else {

print("用戶拒絕通知")

}

}

2.發(fā)送通知(點擊控制器View的時候發(fā)送通知)


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

// 創(chuàng)建通知標識(用于標識哪一個通知)

let identifier = "SimpleNotificationIdentifier"

// 創(chuàng)建通知中的內(nèi)容

let content = UNMutableNotificationContent()

// 設置內(nèi)容

content.body = "我是內(nèi)容"

// 設置通知發(fā)送的時間

// 注意:重復時間必須大于60秒

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

// 創(chuàng)建請求對象

let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

// 獲取通知中心

let center = UNUserNotificationCenter.current()

// 添加本地通知

center.add(request, withCompletionHandler: {(error: Error?) in

if error == nil {

print("本地通知添加成功")

}

})

}

3.展示效果

  • 前臺沒有彈框

  • 后臺/退出應用/通知中心/鎖屏均可以接收到彈框

Paste_Image.png
二.發(fā)送一個帶附件的通知
  • 在iOS10之后發(fā)送通知的時候可以附帶一些內(nèi)容

  • 內(nèi)容包含圖片、GIF圖片、視頻以及音頻(格式最好是caf,否則沒有效果)


/* 設置其他內(nèi)容 */

// 應用文字

content.badge = 10

// 設置通知的聲音

content.sound = UNNotificationSound(named: "win.aac")

// 設置標題

content.title = "我是標題"

// 設置子標題

content.subtitle = "我是子標題"

// 設置附件內(nèi)容

// 附件標識

let attachmentIdentifier = "ImageAttachmentIdentifier"

// 附件URL

if let url = Bundle.main.url(forResource: "70s Electric Piano 52.caf", withExtension: nil) {

do {

let attachment = try UNNotificationAttachment(identifier: attachmentIdentifier, url: url, options: nil)

content.attachments = [attachment]

print("---")

} catch {

print(error)

}

}

  • 展示的效果

圖片

Paste_Image.png

Gif

Paste_Image.png

音頻

Paste_Image.png

視頻

Paste_Image.png
三.對通知的操作
  • 當一個通知添加成功之后,可以對添加成功的通知做一些操作,分別為:

  • 查看即將發(fā)送的通知

  • 取消即將發(fā)送的通知

  • 查看已經(jīng)發(fā)送的通知

  • 取消已經(jīng)發(fā)送的通知


/// 查看即將發(fā)送的通知

@IBAction func showUnsendNotification() {

UNUserNotificationCenter.current().getPendingNotificationRequests { (request: [UNNotificationRequest]) in

print("即將發(fā)送的通知:\(request)")

}

}

/// 刪除即將發(fā)送的通知

@IBAction func removeUnsendNotification() {

// 通過標識刪除某一個通知

// UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: <#T##[String]#>)

// 刪除所有

UNUserNotificationCenter.current().removeAllPendingNotificationRequests()

}

/// 查看發(fā)送成功的通知

@IBAction func showSendedNotification() {

UNUserNotificationCenter.current().getDeliveredNotifications { (notification: [UNNotification]) in

print("查看發(fā)送成功的通知:\(notification)")

}

}

/// 刪除發(fā)送成功的通知

@IBAction func removeSendedNotification() {

// 通過標識刪除某一個發(fā)送成功的通知

// UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: <#T##[String]#>)

// 刪除所有發(fā)送成功的通知

UNUserNotificationCenter.current().removeAllDeliveredNotifications()

}

四.監(jiān)聽通知的點擊
  • 當用戶點擊通知進入App后,監(jiān)聽用戶通知行為

  • 需要設置通知的代理,當用戶點擊了通知后,會通過代理告訴我們

設置代理


UNUserNotificationCenter.current().delegate = self

遵守協(xié)議并實現(xiàn)代理方法


extension ViewController: UNUserNotificationCenterDelegate {

/// 當接收到通知的時候會來到該方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 響應

/// - completionHandler: 成功回調(diào)

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

print("接收到通知\(response)")

completionHandler()

}

/// 當一個通知發(fā)送成功后會來到該方法

///

/// - Parameters:

/// - center: 通知中心

/// - notification: 發(fā)送的通知

/// - completionHandler: 回調(diào)閉包,可以設置在前臺收到通知橫幅

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

print("發(fā)送通知成功\(notification)")

// 在前臺也能接收到通知

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

}

}

五.通知的觸發(fā)條件
  • iOS10與之前的通知的觸發(fā)條件一共有三種

  • 多少時間之后發(fā)送通知

  • 指定日期發(fā)送通知

  • 觸發(fā)區(qū)域發(fā)送通知

  • 在iOS10之后,觸發(fā)條件的類為UNNotificationTrigger

  • 而具體設置需要使用到它的子類

  • UNTimeIntervalNotificationTrigger : 多少時間之后

  • UNCalendarNotificationTrigger : 指定日期

  • UNLocationNotificationTrigger : 指定區(qū)域

1.多少時間之后發(fā)送通知

注意: 如果需要重復,那么時間必須大于60秒

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

2.指定日期發(fā)送通知

可以通過添加年月日時,來固定一個時間發(fā)送通知

// 創(chuàng)建時間組件

var components = DateComponents()

// 設置為日歷時間

components.calendar = Calendar(identifier: .gregorian)

// 每天的早上10點10分發(fā)送通知

components.hour = 10

components.minute = 10

print(components.date)

let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)

3.指定區(qū)域發(fā)送通知

注意:在使用模擬器調(diào)試的過程中,可能會無法顯示,重置模擬器,或者換個模擬器則會解決該問題

// 1.請求授權(iOS8.0之后獲取用戶的位置要主動請求授權,注意在info.plist中配置對應的key)

lazy var locationM: CLLocationManager = {

let locationM = CLLocationManager()

locationM.requestAlwaysAuthorization()

return locationM

}()

// 2.創(chuàng)建區(qū)域觸發(fā)器

let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 12.123, longitude: 123.456), radius: 1000, identifier: "RegionNotification")

locationM.startMonitoring(for: region)

let trigger = UNLocationNotificationTrigger(region: region, repeats: true)

六.額外操作項
1.設置通知的額外信息

// 1.設置額外信息

content.userInfo = ["name": "張三", "age": 18]

// 2.在接收到通知后,可以獲取到額外信息

/// 當接收到通知的時候會來到該方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 響應

/// - completionHandler: 成功回調(diào)

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

print("接收到通知獲取額外信息\(response.notification.request.content.userInfo)")

completionHandler()

}

// 打印為:接收到通知獲取額外信息[AnyHashable("name"): 張三, AnyHashable("age"): 18]

2.設置額外操作項
  • 步驟

  • 注冊操作集合

  • 注冊操作組,添加到操作集合中

  • 注冊操作行為,添加到操作組中

  • 設置通知所用到的操作組


// 1.注冊操作項

// 1.創(chuàng)建操作項

let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回復", options: .foreground)

let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒絕", options: .destructive)

let actions: [UNNotificationAction] = [action1, action2]

// 創(chuàng)建操作組

// identifier: 操作組標識

// actions: 操作組行為

// intentIdentifiers:暫時未發(fā)現(xiàn)該用途

// options: 支持的場景

let categoryIdentifier = "category1"

let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)

// 注冊操作集合(其中設置操作組)

let categories: Set<UNNotificationCategory> = [category]

center.setNotificationCategories(categories)

// 設置該通知用到的額外操作組

content.categoryIdentifier = "category1"

  • 展示效果

  • 點擊回復打開app

  • 點擊拒絕則不會打開app

  • 兩者都會調(diào)用接收通知的代理方法

Paste_Image.png
七.設置快捷回復
  • 操作行為有2個類來實現(xiàn)'UNNotificationAction'以及UNTextInputNotificationAction

  • 其中UNTextInputNotificationAction是'UNNotificationAction'的子類,用于實現(xiàn)快捷回復

  • 下列代碼中的action3 為便捷回復行為


// 1.創(chuàng)建操作項

let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回復", options: .foreground)

let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒絕", options: .destructive)

let action3 = UNTextInputNotificationAction(identifier: "kuaijie", title: "快捷回復", options: .foreground, textInputButtonTitle: "回復按鈕", textInputPlaceholder: "占位字符")

let actions: [UNNotificationAction] = [action1, action2,action3]

// 創(chuàng)建操作組

// identifier: 操作組標識

// actions: 操作組行為

// intentIdentifiers:暫時未發(fā)現(xiàn)該用途

// options: 支持的場景

let categoryIdentifier = "category1"

let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)

// 注冊操作集合(其中設置操作組)

let categories: Set<UNNotificationCategory> = [category]

center.setNotificationCategories(categories)

  • 展示效果
Paste_Image.png
八.通知觸發(fā)的場景
  • 在實際開發(fā)中,前臺獲取通知與后臺獲取通知所要執(zhí)行的邏輯不一致,那么就有必要去判斷一下,當前的通知觸發(fā)的場景

  • 步驟

  • 在獲取到通知的代理方法中獲取該應用的狀態(tài)

  • 判斷當前狀態(tài)


/// 當接收到通知的時候會來到該方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 響應

/// - completionHandler: 成功回調(diào)

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

if let response = response as? UNTextInputNotificationResponse {

print(response.userText)

} else {

print("接收到通知獲取額外信息\(response.notification.request.content.userInfo)")

}

let status = UIApplication.shared.applicationState

switch status {

case .active:

print("在前臺")

case .inactive:

print("進入前臺")

default:

print("在后臺")

}

completionHandler()

}

iOS10遠程推送通知

一.獲取DeviceToken

  • 此處省略配置真機調(diào)試證書通知調(diào)試證書以及通知生產(chǎn)證書步驟

  • 必須保證BundleId與在開發(fā)者中心的AppId一致

  • 必須使用真機

1.注冊通知

  • 需要導入頭文件或者框架UserNotifications

  • 在iOS8.0之后,如果想要用戶接收通知需要主動請求授權,為了能讓該代碼一定被執(zhí)行,一般寫在Appdelegate中


// 1.獲取通知中心

let center = UNUserNotificationCenter.current()

// 2.注冊通知

center.requestAuthorization(options: [.alert,.carPlay,.badge,.sound], completionHandler: {(granted: Bool, error: Error?) in

if error != nil {

return

}

if granted {

print("用戶允許通知")

} else {

print("用戶拒絕通知")

}

})

2.向蘋果服務器申請DeviceToken

  • 獲取方式與iOS8.0一致

// 3.獲取deviceToken

application.registerForRemoteNotifications()

  • 從代理中獲取deviceToken

  • 此處Data打印的是32types,轉(zhuǎn)為NSData即可


/// 當獲取到deviceToken會來到該方法

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

print(NSData(data: deviceToken))

}

/// 注冊失敗會來到該方法

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

print(error)

}

3.開啟遠程推送功能

  • 工程->target->Capabilities->Push

  • 開啟的條件

  • 1.Apple Id 必須配置了遠程推送通知

  • 2.權利文件(打開會自動生成該文件)

4.運行真機,獲取DeviceToken

二.發(fā)送通知

  • 借助PushMeBaby作為服務器向蘋果服務器發(fā)送消息,蘋果服務器推送通知

極光推送

  • 注冊應用

  • 上傳通知證書.p12

  • 集成Jpush SDK

1.注冊Jpush并獲取DeviceToken


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

// 注冊通知

let entity = JPUSHRegisterEntity()

entity.types = Int(JPAuthorizationOptions.alert.rawValue | JPAuthorizationOptions.badge.rawValue | JPAuthorizationOptions.sound.rawValue)

JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)

// 初始化JUSH

JPUSHService.setup(withOption: launchOptions, appKey: "b29ccf03d1e6aca9baa3c34a", channel: "App Store", apsForProduction: false)

return true

}

/// 獲取DeviceToken

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

JPUSHService.registerDeviceToken(deviceToken)

}

/// 注冊失敗

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

print(error)

}

2.設置代理,處理通知


extension AppDelegate : JPUSHRegisterDelegate {

/// 獲取通知

func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {

}

/// 可設置在前臺獲取通知

func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {

let userInfo = notification.request.content.userInfo

let isPushTrigger = notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self) ?? false

if isPushTrigger {

JPUSHService.handleRemoteNotification(userInfo)

}

let value = Int(UNNotificationPresentationOptions.alert.rawValue | UNNotificationPresentationOptions.sound.rawValue | UNNotificationPresentationOptions.badge.rawValue)

completionHandler(value)

// 需要執(zhí)行這個方法,選擇是否提醒用戶,有Badge、Sound、Alert三種類型可以選擇設置

}

}

來源:http://bbs.520it.com/forum.php?mod=viewthread&tid=3020

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容