一.發(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.展示效果
前臺沒有彈框
后臺/退出應用/通知中心/鎖屏均可以接收到彈框
二.發(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)
}
}
- 展示的效果
圖片
Gif
音頻
視頻
三.對通知的操作
當一個通知添加成功之后,可以對添加成功的通知做一些操作,分別為:
查看即將發(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)用接收通知的代理方法
七.設置快捷回復
操作行為有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)
- 展示效果
八.通知觸發(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三種類型可以選擇設置
}
}