You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift iOS:如何访问AnyHashable数据并加载到视图

Hey there! 既然你已经能从通知的userInfo里解析出title和body这些数据了,接下来把它们展示到视图上其实很 straightforward,我给你分几种常见场景来讲解:

把通知数据展示到视图的几种实现方式

1. UIKit项目(AppDelegate 处理通知)

如果你是在AppDelegate的userNotificationCenter(_:didReceive:withCompletionHandler:)方法里解析的userInfo,那要把数据传到目标ViewController有几种办法:

  • 直接跳转并传值:
    先拿到当前的window根控制器,或者通过导航栈push到目标页面,把解析好的title和body传过去。比如:

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        
        // 你的解析代码
        guard let aps = userInfo[AnyHashable("aps")] as? NSDictionary, 
              let alert = aps["alert"] as? NSDictionary, 
              let body = alert["body"] as? String, 
              let title = alert["title"] as? String else {
            completionHandler()
            return
        }
        
        // 获取当前根控制器,假设是UINavigationController
        guard let navController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController else {
            completionHandler()
            return
        }
        
        // 实例化目标ViewController,比如NotificationDetailVC
        let detailVC = NotificationDetailVC()
        detailVC.notificationTitle = title
        detailVC.notificationBody = body
        
        // 跳转过去
        navController.pushViewController(detailVC, animated: true)
        
        completionHandler()
    }
    

    然后在NotificationDetailVC里,只要在viewDidLoad里把值赋值给对应的UILabel就行:

    class NotificationDetailVC: UIViewController {
        var notificationTitle: String?
        var notificationBody: String?
        
        @IBOutlet weak var titleLabel: UILabel!
        @IBOutlet weak var bodyLabel: UILabel!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            titleLabel.text = notificationTitle
            bodyLabel.text = notificationBody
        }
    }
    
  • 用通知中心传值:
    如果不想直接依赖导航栈,也可以用NotificationCenter发送通知,让目标ViewController监听:
    在解析完数据后发送:

    let notificationData = ["title": title, "body": body]
    NotificationCenter.default.post(name: NSNotification.Name("NotificationReceived"), object: nil, userInfo: notificationData)
    

    然后在目标VC的viewDidLoad里监听:

    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(handleNotification(_:)), name: NSNotification.Name("NotificationReceived"), object: nil)
    }
    
    @objc func handleNotification(_ notification: Notification) {
        guard let data = notification.userInfo as? [String: String],
              let title = data["title"],
              let body = data["body"] else { return }
        titleLabel.text = title
        bodyLabel.text = body
    }
    
    // 记得deinit里移除监听
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    

2. UIKit项目(SceneDelegate 处理通知)

如果你的项目是用SceneDelegate的(iOS 13+),那处理逻辑类似,只是获取根控制器的方式变了:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    // 解析数据...
    
    // 获取当前scene的根控制器
    guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = scene.windows.first,
          let navController = window.rootViewController as? UINavigationController else {
        completionHandler()
        return
    }
    
    // 后续跳转传值和上面一样
    let detailVC = NotificationDetailVC()
    detailVC.notificationTitle = title
    detailVC.notificationBody = body
    navController.pushViewController(detailVC, animated: true)
    
    completionHandler()
}

3. SwiftUI项目

如果是SwiftUI项目,你可以用@Published属性结合ObservableObject来传递数据:
首先,创建一个全局的通知管理器:

class NotificationManager: ObservableObject {
    static let shared = NotificationManager()
    @Published var receivedNotification: (title: String, body: String)?
}

然后在通知处理的地方(比如App.swift里的相关回调或者UNUserNotificationCenterDelegate方法):

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    // 解析数据...
    
    NotificationManager.shared.receivedNotification = (title: title, body: body)
    completionHandler()
}

最后在你的SwiftUI视图里监听这个@Published属性:

struct NotificationView: View {
    @StateObject private var notificationManager = NotificationManager.shared
    
    var body: some View {
        VStack {
            if let notification = notificationManager.receivedNotification {
                Text(notification.title)
                    .font(.title)
                Text(notification.body)
                    .font(.body)
                    .padding()
            } else {
                Text("No notification received")
            }
        }
    }
}

关键注意事项

  • 确保在更新UI的时候是在主队列操作,虽然上面的方法大多已经在主队列,但如果你的解析是异步执行的,记得用DispatchQueue.main.async包裹UI更新代码:
    DispatchQueue.main.async {
        self.titleLabel.text = title
        self.bodyLabel.text = body
    }
    
  • 如果App在后台被唤醒,要确保视图已经加载完成再赋值,不然可能会出现UI控件为nil的情况,用通知中心或者ObservableObject的方式会更稳妥。

内容的提问来源于stack exchange,提问作者user9606220

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:58:10