一、文章实现功能背景
(1)实现功能:用户收到推送消息,点击后跳转到具体页面
(2)平台:iOS SwiftUI
二、准备工作
iOS工程开启消息通知等,APP已经能实现收到消息推送。
这一步自行搜索相关文章
三、思路和实现
在SwiftUI里实现的模块通知流程如下:
sequenceDiagram
消息体->>AppDelegate: ①ntfType传递消息类型
AppDelegate->>ContentView总页面: ②NotificationCenter.default.post ntfType消息类型
ContentView总页面-)目标页面: ③例如设置tab
(1)消息体里的增加自定义消息类型
{
"Simulator Target Bundle": "com.xxx", //com.xxx你的app包标识
"aps":{
"alert":{
"title":"测试",
"subtitle":"远程推送",
"body":"这是一条从远处而来的通知"
},
"sound":"default",
"badge":1
},
"ntfType":"rank_like", //这里是消息类型。ntfType
}
(2)在AppDelegate里收到远程推送消息,通知到APP 总入口ContentView
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
NSLog("[Mtlog] userNotificationCenter background remote notification")
//可以这样拿到payload 里自定义的key内容, 假设key为shit11 那么内容为 response.notification.request.content.userInfo["shit11"] as! String
print(#function, "delegate user response", response)
//获取这里做分发
if let notificationtype = response.notification.request.content.userInfo["ntfType"] as? String{
//rank_like 排行榜点赞 new_user_works 关注的用户发布新作品
if notificationtype == "rank_like" || notificationtype == "new_user_works" {
NotificationCenter.default.post(name: Notification.Name("ntfType_remote_notification"), object: nil, userInfo: ["ntfType": notificationtype])
mtlog.info("send ntfType_remote_notification, ntfType:\(notificationtype)")
}
}
//要在处理完成后调用 completionHandler()告知完成
completionHandler()
}
上面那个userNotificationCenter是APP处于后台时才会触发的,如果想处理APP在前台时也响应远程推送,要用下面这个函数
//app还在运行时收到消息推送代理。app在后台不会进入这里的
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
//可以这样拿到payload 里自定义的key内容, 假设key为shit11 那么内容为 notification.request.content.userInfo["shit11"] as! String
print(#function, "delegate willPresent", notification)
}
(3)在ContentView总入口里跳转到指定页面
struct ContentView: View {
var body: some View {
ZStack{
NavigationView{
//自定义tabview
ZStack(alignment:.bottom){
//正文页面
switch tabSelection{
case 0:
...
}
//接收Notification, 拉起指定页面
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("ntfType_remote_notification"))){
data in
print(#function, "ntfType_remote_notification", data)
if let ntfType = data.userInfo?["ntfType"] as? String{
if ntfType == "rank_like"{
//rank_like消息,跳转排行榜
self.tabSelection = 4
//设置跳转参数
viewManagerModel.setJumpParam(data: "jumpRichest")
}else if ntfType == "new_user_works"{ //关注的用户发布新作品消息
self.tabSelection = 2 //跳转到用户作品页
viewManagerModel.setJumpParam(data: "jumpFollowSkinsView")
}
}
}
}
如果在tab页面里,还有跳转页, 则设置业内跳转参数,通过全局的viewManagerModel给到目标tab页。目标tab页在它自己的onAppear里处理
//目标tab页的onAppear处理
.onAppear(){
print(#function, "locale", locale.identifier, locale)
// skins.switchTrendsType(trendsType: self.trendsSlection)
//处理跳转逻辑
if let jumpParam = ViewManagerModel.shared.getJumpParam() as? String{
switch jumpParam{
case "jumpFollowSkinsView":
ugcSlection = .follow
break
default:
break
}
}
}
还有一点例外要处理, 就是目标tab页处在当前活动页面时,并不会触发onAppear。那么要直接由Appdelegate的NotificationCenter来触发
//目标tab页为点击远程推送的当前活动页时,不会触发onAppear,这时候要直接响应Appdelegate的NotificationCenter来触发
.onReceive(NotificationCenter.default.publisher(for: Notification.Name("ntfType_remote_notification"))){
data in
print(#function, "ntfType_remote_notification", data)
if let ntfType = data.userInfo?["ntfType"] as? String{
if ntfType == "new_user_works"{ //关注的用户发布新作品消息
ugcSlection = .follow
}
}
}