Flutter中Apple Wallet设为Default Card时界面冻结问题求助
解决Flutter中Apple Wallet设为默认卡片后界面冻结无法关闭的问题
核心原因
Apple系统弹出的“设为默认卡片”弹窗是独立于Flutter界面的系统级弹窗,默认情况下Flutter代码不会监听这个操作完成后的回调,导致设置完成后没有触发界面关闭逻辑。
具体解决方案
1. 监听完整的Wallet事件回调
无论你使用第三方插件(如flutter_passkit)还是自定义原生集成,都需要覆盖设置默认卡片完成的事件:
- iOS原生端需要监听
PKPassLibraryDidChangeNotification系统通知,该通知会在Wallet内卡片状态变化(包括设为默认)时触发。 - Flutter端通过
MethodChannel接收原生传递的状态信号,执行界面关闭逻辑。
2. iOS原生端代码示例
在处理Wallet添加的UIViewController中添加通知监听:
import PassKit class WalletAddViewController: UIViewController, PKAddPaymentPassViewControllerDelegate { var flutterChannel: FlutterMethodChannel? override func viewDidLoad() { super.viewDidLoad() // 注册卡片状态变化通知 NotificationCenter.default.addObserver( self, selector: #selector(passLibraryChanged(_:)), name: NSNotification.Name.PKPassLibraryDidChange, object: nil ) } @objc func passLibraryChanged(_ notification: Notification) { // 校验是否是目标卡片设为默认的操作 let passLibrary = PKPassLibrary() if let defaultPass = passLibrary.defaultPaymentPass, defaultPass.primaryAccountIdentifier == "你的卡片唯一标识" { // 通知Flutter端关闭界面 flutterChannel?.invokeMethod("onDefaultCardSet", arguments: nil) } } // 原有卡片添加完成的回调 func addPaymentPassViewControllerDidFinish(_ controller: PKAddPaymentPassViewController) { controller.dismiss(animated: true) flutterChannel?.invokeMethod("onCardAdded", arguments: nil) } }
3. Flutter端代码示例
通过MethodChannel监听原生事件并处理关闭:
import 'package:flutter/services.dart'; class WalletAddScreen extends StatefulWidget { @override _WalletAddScreenState createState() => _WalletAddScreenState(); } class _WalletAddScreenState extends State<WalletAddScreen> { late MethodChannel _walletChannel; @override void initState() { super.initState(); _walletChannel = MethodChannel('com.your.app/wallet'); _walletChannel.setMethodCallHandler((call) async { switch (call.method) { case 'onDefaultCardSet': case 'onCardAdded': // 确保界面未销毁时执行关闭 if (mounted) { Navigator.pop(context); } break; } }); } // 添加至Wallet按钮逻辑 void _triggerAddToWallet() { _walletChannel.invokeMethod('addPaymentPass'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('添加至Apple Wallet')), body: Center( child: ElevatedButton( onPressed: _triggerAddToWallet, child: const Text('添加至Wallet'), ), ), ); } }
4. 关键注意事项
- 必须匹配卡片的唯一标识(如
primaryAccountIdentifier),避免误触发关闭逻辑。 - 加入
mounted判断,防止界面已销毁时执行Navigator.pop引发崩溃。 - 分别测试“添加后不设为默认”和“添加后设为默认”两种场景,确保两种流程都能正常关闭界面。
内容的提问来源于stack exchange,提问作者Andy Lebowitz
相关产品推荐
相关产品推荐

