23. 推送实战
推送链路的核心是:申请权限 → 注册 APNs → 获取 Device Token → 处理通知。
一、申请通知权限
import UserNotifications
func requestNotification() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
if granted {
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
}
}
}
二、获取 Device Token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
print("token: \(token)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("register failed: \(error)")
}
三、前台展示通知
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .sound, .badge])
}
}
四、点击通知处理
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// 根据 userInfo 跳转页面
completionHandler()
}
五、通知分类与按钮
let reply = UNNotificationAction(identifier: "reply", title: "回复", options: [])
let mark = UNNotificationAction(identifier: "mark", title: "标记已读", options: [])
let category = UNNotificationCategory(identifier: "message",
actions: [reply, mark],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
服务端下发时在 payload 中指定 category 即可。
六、角标管理
UIApplication.shared.applicationIconBadgeNumber = 0
推送的可靠性取决于:权限引导清晰、token 上报稳定、通知落地明确。