iOS自定义点击推送消息跳转指定页面

1,507 阅读2分钟

一、文章实现功能背景

(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
                }
            }
        }