iOS Swift 推送通知完整实现教程(前台/后台/杀死状态 全覆盖跳转)
2026/5/15 2:48:17 网站建设 项目流程

一、前言

远程推送通知是iOS开发中高频必备功能,绝大多数App都需要实现推送消息提醒、点击通知跳转指定业务页面。iOS推送分为三种运行状态,开发中必须全部兼容:

  1. 前台运行:App处于打开状态,直接接收推送弹窗

  2. 后台挂起:App未关闭、退至后台,点击通知唤起App并跳转

  3. 进程杀死:App彻底关闭、进程销毁,点击通知冷启动App并跳转

本文基于Swift + iOS 10+,依托UserNotifications框架,提供一套企业级可直接复用的完整推送代码,包含权限注册、DeviceToken获取、三种状态推送监听、统一页面跳转逻辑,代码经过真机测试,开箱即用。

二、前期工程配置(必看)

2.1 开启推送能力

Xcode -> Targets -> Signing & Capabilities,添加以下能力:

  • Push Notifications:推送权限

  • Background Modes:后台模式,勾选Remote notifications

2.2 依赖库说明

本文解析推送Json数据使用SwiftyJSON,若无该依赖,可手动使用原生字典解析。

2.3 证书配置

远程推送必须配置APNs推送证书,开发环境使用开发证书,生产环境使用发布证书,否则无法获取DeviceToken、接收不到推送。

三、完整代码实现

3.1 引入依赖、遵守代理

importUIKitimportUserNotificationsimportSwiftyJSON@mainclassAppDelegate:UIResponder,UIApplicationDelegate,UNUserNotificationCenterDelegate{varwindow:UIWindow?funcapplication(_application:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey:Any]?)->Bool{// 1. 注册推送权限registerForPushNotifications(application:application)// 2. 处理App被杀死状态下,点击通知冷启动跳转handlePushWhenAppKilled(launchOptions:launchOptions)returntrue}}

3.2 推送权限注册

兼容iOS10前后版本,申请弹窗、声音、角标权限,授权成功后注册远程推送,获取设备Token。

// MARK: - 注册推送权限extensionAppDelegate{funcregisterForPushNotifications(application:UIApplication){if#available(iOS10.0,*){letcenter=UNUserNotificationCenter.current()center.delegate=self// 申请通知权限:提示框、声音、角标center.requestAuthorization(options:[.sound,.alert,.badge]){granted,erroringuardgrantedelse{print("用户拒绝通知权限")return}// 权限授权成功,获取通知配置并注册Tokenself.getNotificationSettings()}}else{// iOS10 以下低版本适配letsettings=UIUserNotificationSettings(types:[.sound,.alert,.badge],categories:nil)application.registerUserNotificationSettings(settings)application.registerForRemoteNotifications()}}// 获取通知授权状态,注册远程推送funcgetNotificationSettings(){if#available(iOS10.0,*){UNUserNotificationCenter.current().getNotificationSettings{settingsinguardsettings.authorizationStatus==.authorizedelse{return}DispatchQueue.main.async{UIApplication.shared.registerForRemoteNotifications()}}}}}

3.3 获取DeviceToken

DeviceToken是设备唯一推送标识,需要上传至服务端,用于精准推送。

// MARK: - DeviceToken 回调extensionAppDelegate{// 注册成功,获取设备Tokenfuncapplication(_application:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){lettoken=deviceToken.map{String(format:"%02.2hhx",$0)}.joined()print("推送DeviceToken:\(token)")// 此处上传Token至后端服务器}// 注册推送失败回调funcapplication(_application:UIApplication,didFailToRegisterForRemoteNotificationsWithError error:Error){print("推送注册失败:\(error.localizedDescription)")}}

3.4 处理App杀死状态推送跳转

App进程彻底销毁时,点击通知会触发冷启动,通过launchOptions获取推送载荷,实现页面跳转。

// MARK: - App被杀死 点击通知冷启动跳转extensionAppDelegate{funchandlePushWhenAppKilled(launchOptions:[UIApplication.LaunchOptionsKey:Any]?){guardletoptions=launchOptionselse{return}// 获取远程推送数据ifletnotification=options[.remoteNotification]as?[String:Any]{print("APP杀死状态,点击通知启动:\(notification)")letuserInfo=notification// 解析自定义推送字段letkey=userInfo["key"]as?String??""letvalue=userInfo["value"]as?Int??0// 根据业务key判断跳转页面ifkey=="通知传过来的key值"{handlePushForNavigationTo(key:value)}}}}

3.5 通用页面跳转工具方法

适配所有推送场景,自动获取当前顶层控制器,避免页面栈覆盖问题,采用Present方式跳转,同时标记通知来源。

// MARK: - 推送通用跳转方法extensionAppDelegate{funchandlePushForNavigationTo(key:Int){guardkey>0else{return}// 获取根控制器guardletrootVC=window?.rootViewControllerelse{return}vartopVC=rootVC// 循环遍历,拿到当前最顶层控制器whileletpresentedVC=topVC.presentedViewController{topVC=presentedVC}// 实例化跳转目标控制器(根据自身项目修改)ifletnextViewController=UIStoryboard(name:"Main",bundle:nil).instantiateViewController(withIdentifier:"ViewController")as?ViewController{nextViewController.key值=key// 标记来源:通知跳转nextViewController.isFromNotification=trueletnavController=UINavigationController(rootViewController:nextViewController)navController.modalPresentationStyle=.fullScreen// 顶层控制器弹出新页面topVC.present(navController,animated:true,completion:nil)}}}

3.6 推送代理方法(前台/后台)

处理App前台接收推送、后台点击推送两种场景,统一解析推送参数、执行跳转逻辑。

// MARK: - UNUserNotificationCenter 推送代理extensionAppDelegate:UNUserNotificationCenterDelegate{// 后台、挂起状态:点击通知触发@available(iOS10.0,*)funcuserNotificationCenter(_center:UNUserNotificationCenter,didReceive response:UNNotificationResponse,withCompletionHandler completionHandler:@escaping()->Void){letuserInfo=response.notification.request.content.userInfoletjson=JSON(userInfo)letkey=json["key"].stringValueletvalue=json["value"].intValueprint("后台点击通知:key=\(key),value=\(value)")// 根据key跳转对应页面switchkey{case"通知传过来的key值":handlePushForNavigationTo(key:value)breakdefault:break}completionHandler()}// 前台运行状态:收到推送即时触发@available(iOS10.0,*)funcuserNotificationCenter(_center:UNUserNotificationCenter,willPresent notification:UNNotification,withCompletionHandler completionHandler:@escaping(UNNotificationPresentationOptions)->Void){letuserInfo=notification.request.content.userInfoletjson=JSON(userInfo)print("前台收到推送:\(userInfo)")print("推送key:\(json["key"].stringValue)")// 前台展示:弹窗、声音、角标completionHandler([.alert,.badge,.sound])}}

四、推送三种状态逻辑总结

App运行状态触发方法使用场景
前台运行willPresentApp打开状态,直接弹窗展示推送
后台挂起didReceive退到后台,点击通知唤起App并跳转
进程杀死launchOptions彻底关闭App,冷启动解析推送跳转

五、开发注意事项(避坑指南)

5.1 权限相关

  • iOS13+ 需要在Info.plist添加权限描述:NSUserNotificationUsageDescription,否则安装直接崩溃;

  • 必须用户手动授权,静默授权无法实现。

5.2 DeviceToken问题

  • 模拟器无法获取DeviceToken,必须使用真机调试;

  • 重装App、更换设备、还原手机,DeviceToken会改变,后端需做兼容处理。

5.3 页面跳转坑点

  • 禁止直接获取根控制器跳转,必须循环遍历拿到当前最顶层控制器,防止页面被遮挡、跳转无反应;

  • 推送跳转建议使用Present模态弹出,不破坏原有项目导航栈。

5.4 推送载荷规范

  • 后端推送JSON必须包含aps标准字段,自定义业务字段放置同级;

  • 杀死状态下,iOS10及以上不再走代理方法,只能通过launchOptions解析数据。

5.5 后台推送限制

  • 未开启后台推送权限,App后台无法接收静默推送;

  • 系统会限制推送频率,频繁推送会被系统节流拦截。

六、总结

本文完整实现了iOS Swift远程推送全套功能,适配iOS10+所有机型,覆盖前台、后台、杀死三种核心场景。代码封装简洁、耦合度低,跳转逻辑通用,可直接接入企业项目。开发中重点注意:真机调试、证书配置、顶层控制器跳转、杀死状态数据解析四大关键点,规避推送常见Bug。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询