Swift4新手求助:如何在ViewController中使用AppDelegate里的变量?
嘿,作为Swift新手碰到这种跨组件传值的问题太正常啦!我给你分享几个项目里常用的解决方案,你可以根据自己的场景选:
方法一:用通知中心(NotificationCenter)传递
这是轻量跨组件传值的首选,步骤很清晰:
- 在AppDelegate拿到Token后发送通知:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { if let refreshedToken = InstanceID.instanceID().token() { print("InstanceID token: \(refreshedToken)") // 发送携带Token的通知 NotificationCenter.default.post( name: NSNotification.Name("DidReceiveFCMToken"), object: nil, userInfo: ["fcmToken": refreshedToken] ) } }
- 在ViewController里监听通知并处理:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 注册通知监听 NotificationCenter.default.addObserver( self, selector: #selector(handleFCMTokenReceived(_:)), name: NSNotification.Name("DidReceiveFCMToken"), object: nil ) } // 处理Token的方法 @objc private func handleFCMTokenReceived(_ notification: Notification) { if let token = notification.userInfo?["fcmToken"] as? String { // 这里就可以用Token啦 print("拿到FCM Token:\(token)") } } // 页面销毁时移除监听,避免内存泄漏 deinit { NotificationCenter.default.removeObserver(self) } }
方法二:用单例类存储Token
如果Token是全局需要用到的,单例会是很方便的选择:
- 创建一个单例管理类
TokenManager.swift:
class TokenManager { // 全局唯一实例 static let shared = TokenManager() // 存储FCM Token的变量 var fcmToken: String? // 私有化构造方法,确保只能通过shared获取实例 private init() {} }
- 在AppDelegate里给单例赋值:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { if let refreshedToken = InstanceID.instanceID().token() { print("InstanceID token: \(refreshedToken)") TokenManager.shared.fcmToken = refreshedToken } }
- 在ViewController里随时获取:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 直接从单例取Token,记得判空 if let token = TokenManager.shared.fcmToken { print("从单例拿到的Token:\(token)") } } }
小贴士:如果需要重启App后还能拿到Token,可以把它存在UserDefaults里,在单例里加个存/取的方法就行~
方法三:用闭包回调传递
如果你的ViewController是在AppDelegate之后初始化的,闭包也是个不错的选择:
- 在ViewController里定义闭包属性:
class ViewController: UIViewController { // 定义接收Token的闭包 var onTokenReceived: ((String) -> Void)? override func viewDidLoad() { super.viewDidLoad() // 设置闭包的处理逻辑 onTokenReceived = { [weak self] token in guard let self = self else { return } print("通过闭包拿到的Token:\(token)") // 在这里处理你的Token逻辑 } } }
- 在AppDelegate里拿到Token后调用闭包:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { if let refreshedToken = InstanceID.instanceID().token() { print("InstanceID token: \(refreshedToken)") // 假设根控制器是你的ViewController,实际根据页面结构调整 if let rootVC = window?.rootViewController as? ViewController { rootVC.onTokenReceived?(refreshedToken) } } }
注意:闭包要加[weak self]避免循环引用哦~
内容的提问来源于stack exchange,提问作者Hybrid engineer
相关产品推荐
相关产品推荐

