扩展 AppDelegate, 在合适的地方调用
//
// AppDelegate+Notification.swift
//
// Created by Cy on 2019/12/11.
// Copyright © 2019 ceeyang. All rights reserved.
//
import UIKit
import UserNotifications
import CloudPushSDK
/// APP 移动推送开发流程
/// ① APP 申请通知功能
/// ② 监听 APP 申请通知回调
/// ③ 通知权限申请成功 初始化第三方通知组件
/// ④ 讲申请通知权限成功后的 devicetoken 传到第三方
/// ⑤ 处理通知接受到的回调
// MARK: - Appdelegate Notification Extension
extension AppDelegate {
/// 初始化阿里云移动推送组件
func initCloudPush(_ launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
/// 阿里云移动推送集成的时候会让你导入一个 plist 文件, 里面有阿里云推送所需数据 , 可以直接调用 autoInit 方法
CloudPushSDK.autoInit { (result) in
if result?.success == true {
print("Init CloudPush Success, deviceId: \(String(describing: CloudPushSDK.getDeviceId()))")
} else {
print("Init CloudPush Failed, error: \(String(describing: result?.error))")
}
}
CloudPushSDK.sendNotificationAck(launchOptions)
}
/// 阿里云移动推送绑定账号
/// - Parameter account: 账号
func bindAccount(account: String) {
CloudPushSDK.bindAccount(account) { (result) in
if result?.success == true {
print("CloudPushSDK: bindAccount Success;")
} else {
print("CloudPushSDK: bindAccount Failed;\nerror: \(result?.error?.localizedDescription ?? "")")
}
}
}
/// 解绑账号
func unbindAccount() {
CloudPushSDK.unbindAccount { (result) in
if result?.success == true {
print("CloudPushSDK: bindAccount Success;")
} else {
print("CloudPushSDK: bindAccount Failed;\nerror: \(result?.error?.localizedDescription ?? "")")
}
}
}
/// 在合适的地方调用, 用于申请通知权限
func registerNotification() {
/// application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {}
/// 上述方法中的 application === UIApplication.shared
let center = UNUserNotificationCenter.current()
center.delegate = self
center.getNotificationSettings { (settings) in
/// 已经允许
if settings.authorizationStatus == .authorized { return }
/// 被拒绝
if settings.authorizationStatus == .denied { return }
/// 申请权限
center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted: Bool, error: Error?) in
DispatchQueue.main.async {
if granted && error == nil {
/// 注册远程推送
UIApplication.shared.registerForRemoteNotifications()
} else {
print("RequestAuthorization Filed: Error\(error?.localizedDescription ?? "")")
}
}
}
}
}
/// 申请通知权限成功
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
/// 苹果推送注册成功回调,将苹果返回的deviceToken上传到CloudPush服务器
CloudPushSDK.registerDevice(deviceToken) { (result) in
if result?.success == true {
print("Register Device Success; DeviceToken:\(deviceToken.base64EncodedString())")
} else {
print("Register Device Failed;Error:\(result?.error?.localizedDescription ?? "")")
}
}
}
/// 申请通知权限失败
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
// 注册失败后的结果, 可以在这里记录失败结果, 以后再伺机弹框给用户打开通知
print("Register Notification Failed;Error:\(error.localizedDescription)")
}
}
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
/// APP 处于后台状态收到通知
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("didReceive response: \(response.notification.request.content.userInfo)")
/// TODO: 接收到通知,处理业务逻辑
}
/// app 处于前台状态收到通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
/// let userInfo = notification.request.content.userInfo
/// 自定义 APP 内通知, 省略代码 QQ的前台通知不走系统通知平台, APP 内震动+显示消息条数 后台通知走系统通知
/// or
/// 转发通知, 继续使用通知栏进行提示, 目测微信的APP内通知也是直接转发[APP 前台与后台 通知都是系统通知]
completionHandler([.alert,.sound])
}
}
extension UIApplication {
/// 本地通知 调用方法如下
///
/// UIApplication.localNotification(title: "title", subTitle: "subtitle",body: "body", badge: 1,userInfo: ["paramsId":"23333"])
///
/// - Parameters:
/// - title: 标题
/// - subTitle: 副标题
/// - body: 内容
/// - badge: 角标数字, APP 右上角提示数字
/// - userInfo: 参数
/// - notificationTrigger: 通知类型, 详情请查阅 UNNotificationTrigger, 默认5 秒后发送通知不重复
public static func localNotification(title: String?=nil,
subTitle: String?=nil,
body: String?=nil,
badge: NSNumber?=nil,
userInfo: [AnyHashable : Any]?=nil,
notificationTrigger: UNNotificationTrigger?=nil) {
var trigger = notificationTrigger
if trigger == nil {
trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
}
// 2. 创建推送的内容 UNMutableNotificationContent
let content = UNMutableNotificationContent()
content.title = title ?? ""
content.subtitle = subTitle ?? ""
content.body = body ?? ""
content.badge = badge ?? 0
content.sound = UNNotificationSound.default
content.userInfo = userInfo ?? [:]
// // 推送交互操作
// content.categoryIdentifier = @"Dely_locationCategory";
// [self addNotificationAction];
// 3. 创建推送请求 UNNotificationRequest
let request = UNNotificationRequest(identifier: "com.xakj.local.notification", content: content, trigger: trigger)
// 4. 推送请求添加到推送管理中心 UNUserNotificationCenter
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: { (error) in
if error == nil {
print("推送已添加成功")
}
})
}
}
AppDelegate:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
public static let shared = AppDelegate()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
/// 初始化通知,初始化其他通知组件
initCloudPush(launchOptions)
/// Other Code
return true
}
}
在其他地方,准备提示申请权限的时候调用:
AppDelegate.shared.registerNotification()