watchOS与iOS间Handoff功能失效,寻求从Apple Watch唤起iPhone应用方案
排查Apple Watch与iPhone间Handoff失效的问题
从你贴的代码来看,核心逻辑是没问题的,但Handoff要正常跑起来,还有几个关键配置和细节容易被忽略,我帮你逐一梳理:
1. 必须在两端的Info.plist中声明Activity Type
Handoff要求iOS和watchOS项目的Info.plist里都注册你用到的sharedUserActivityType,否则系统无法识别这个活动类型。
在两个项目的Info.plist中添加以下配置:
<key>NSUserActivityTypes</key> <array> <string>com.mycompanyname.myappname.openApp</string> </array>
你可以直接在Xcode的Info面板里添加,也可以手动编辑plist文件。
2. 确认设备满足Handoff运行条件
Handoff有硬性的设备要求,少一个都不行:
- iPhone和Watch必须登录同一个Apple ID,并且开启双重认证
- 两端都要打开Handoff开关:
- iPhone:设置 → 通用 → AirDrop与Handoff → 开启“允许Handoff”
- Watch:打开iPhone上的Watch App → 通用 → 开启“启用Handoff”
- 设备要处于蓝牙连接范围内,并且连接到同一个Wi-Fi网络(或者同时开启Wi-Fi和蓝牙,无需同一Wi-Fi,但蓝牙必须正常连接)
3. Watch端的UserActivity调用优化
你用的updateUserActivity方法是对的,但有时候手动创建NSUserActivity并标记为当前活跃会更可靠,试试替换成这段代码:
// Watch控制器按钮点击事件里 let activity = NSUserActivity(activityType: sharedUserActivityType) activity.userInfo = [sharedIdentifierKey: 123456] activity.becomeCurrent()
另外要确保这段代码是在Watch应用处于活跃状态时调用的,比如可以加个打印日志验证按钮点击事件是否真的触发了。
4. iOS端的回调方法兼容性检查
如果你的iOS项目是iOS 13及以上,并且采用了Scene架构(大部分新项目都是),那么原来在AppDelegate里的continueUserActivity方法不会被调用,需要转到SceneDelegate中实现对应的方法:
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == sharedUserActivityType else { return } if let userInfo = userActivity.userInfo as? [String: Any], let identifier = userInfo[sharedIdentifierKey] as? Int { // 执行你的操作,比如弹出提示 let alert = UIAlertController(title: "Handoff", message: "收到ID:\(identifier)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) // 找到根控制器弹出alert if let windowScene = scene as? UIWindowScene, let rootVC = windowScene.windows.first?.rootViewController { rootVC.present(alert, animated: true) } } }
如果你的项目还在用传统的AppDelegate架构,要确保方法签名是Swift 3+的正确格式(旧语法的参数类型会导致系统找不到这个方法):
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if userActivity.activityType == sharedUserActivityType { if let userInfo = userActivity.userInfo as? [String: Any], let identifier = userInfo[sharedIdentifierKey] as? Int { // 你的操作逻辑 let alert = UIAlertView(title: "Handoff", message: "ID: \(identifier)", delegate: nil, cancelButtonTitle: "OK") alert.show() } } return true }
5. 测试时的注意事项
- 不要用模拟器测试!Handoff在模拟器上的支持非常有限,必须用真实的iPhone和Watch设备
- 触发Watch的按钮后,在iPhone的锁屏界面左下角会出现Handoff的图标(就是你Watch应用的图标),向上滑动就能打开对应的iPhone应用;或者在App Switcher里也能看到Handoff的入口
按照这些步骤逐一排查,应该就能解决Handoff失效的问题了。
内容的提问来源于stack exchange,提问作者iGatiTech
相关产品推荐
相关产品推荐

