请求远程通知权限后执行模态Segue失败问题求助
解决远程通知权限授予后无法执行模态Segue的问题
你的问题核心在于**registerANSForApplication函数里完全没有调用传入的block闭包**,导致ViewController中你写的回调代码根本没有机会执行,Segue自然不会被触发。我们一步步来修复:
1. 修复AppDelegate中的权限回调逻辑
首先修改registerANSForApplication函数,在权限请求的回调里正确调用传入的block,同时要注意UI操作必须在主线程执行,所以调用block时要切换到主队列:
func registerANSForApplication(_ application: UIApplication,withBlock block: @escaping (_ granted:Bool) -> (Void)){ InstanceID.instanceID().instanceID { (result, error) in if let error = error { print("Error fetching remote instange ID: \(error)") } else if let result = result { print("Remote instance ID token: \(result.token)") AppDelegate.isToken = result.token } } let current = UNUserNotificationCenter.current() let options : UNAuthorizationOptions = [.sound, .badge, .alert] current.requestAuthorization(options: options) { (granted, error) in // 先处理错误情况,如果有错误,告知权限请求失败 if let error = error { print(error.localizedDescription) DispatchQueue.main.async { block(false) } return } // 无论用户允许还是拒绝,都在主线程调用block传递结果 DispatchQueue.main.async { block(granted) } if granted { Messaging.messaging().delegate = self current.delegate = self application.registerForRemoteNotifications() } } }
这里的关键变化:
- 在权限请求回调中,无论成功/失败、允许/拒绝,都通过
DispatchQueue.main.async调用传入的block,确保UI操作(Segue)在主线程执行。 - 错误情况下也调用block,避免回调永远不执行的死锁情况。
2. 优化ViewController中的回调逻辑
你的ViewController代码可以保留,但建议增加granted判断(仅在用户允许时执行Segue),同时添加弱引用避免循环引用:
let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.registerANSForApplication(UIApplication.shared) { [weak self] granted in guard let self = self else { return } if granted { self.performSegue(withIdentifier: "MembershipVC", sender: nil) } else { // 可选:用户拒绝权限时的处理逻辑,比如提示用户开启权限 print("用户拒绝了通知权限") } }
添加[weak self]是为了防止ViewController因循环引用无法被正确释放。
3. 额外排查点
如果修改后还是无法执行Segue,检查以下几点:
- 确认Storyboard中的Segue标识符完全匹配"MembershipVC"(注意大小写和拼写)。
- 确认Segue的类型是模态(Modal),且源ViewController是当前正在显示的ViewController。
- 建议在
viewDidAppear中触发权限请求,避免在viewDidLoad中过早调用时ViewController还未加载到视图层级。
内容的提问来源于stack exchange,提问作者TheSwiftApprentice35
相关产品推荐
相关产品推荐

