iOS15 SwiftUI VPN应用Siri快捷方式连接/断开功能配置求助
iOS 15 VPN应用Siri快捷方式配置方案
问题背景
开发iOS 15目标版本的VPN应用,需实现Siri快捷功能:用户打开YouTube等特定App时,自动触发VPN连接/断开操作。已通过NSUserActivity捐赠快捷方式并配置Info.plist的activityTypes,但功能未生效,现有代码见下方。
现有代码问题排查
- 捐赠时机不合理:仅在App启动时执行一次捐赠,系统难以关联用户实际行为,无法有效触发场景预测
- Activity配置缺失:未添加场景关联的关键词或目标App标识,Siri无法识别触发场景
- 后台操作权限不足:VPN连接/断开操作在后台执行时,未延长App后台生命周期,可能被系统终止
- Info.plist配置需验证:需确保
NSUserActivityTypes数组包含正确的ActivityType字符串
修正后的可行配置方案
1. 调整捐赠时机,关联用户实际操作
将快捷方式捐赠逻辑从App启动时,移至用户手动完成VPN连接/断开操作的回调中,确保系统收录用户真实行为:
// 示例:VPN连接成功后调用 func vpnDidConnect() { donateConnectVPNShortcut() } // 示例:VPN断开成功后调用 func vpnDidDisconnect() { donateDisconnectVPNShortcut() }
2. 完善NSUserActivity场景关联配置
为Activity添加关键词和目标App标识,帮助Siri识别触发场景(如YouTube):
private func donateConnectVPNShortcut() { let title = NSLocalizedString("siriShortcutConnectVPNTitle", comment: "Title for Connect VPN Shortcut") let activity = NSUserActivity(activityType: Constants.connectVPNSiriActivityType) activity.title = title activity.suggestedInvocationPhrase = title activity.isEligibleForSearch = true activity.isEligibleForPrediction = true activity.persistentIdentifier = NSUserActivityPersistentIdentifier(Constants.connectVPNSiriActivityType) // 添加场景关联关键词和目标App Bundle ID activity.keywords = Set(["YouTube", "视频", "VPN连接"]) activity.userInfo = ["triggerBundleID": "com.google.ios.youtube"] activity.becomeCurrent() } private func donateDisconnectVPNShortcut() { let title = NSLocalizedString("siriShortcutDisconnectVPNTitle", comment: "Title for disconnect VPN Shortcut") let activity = NSUserActivity(activityType: Constants.disconnectVPNSiriActivityType) activity.title = title activity.suggestedInvocationPhrase = title activity.isEligibleForSearch = true activity.isEligibleForPrediction = true activity.persistentIdentifier = NSUserActivityPersistentIdentifier(Constants.disconnectVPNSiriActivityType) activity.keywords = Set(["YouTube", "视频", "VPN断开"]) activity.userInfo = ["triggerBundleID": "com.google.ios.youtube"] activity.becomeCurrent() }
3. 验证Info.plist配置
确保NSUserActivityTypes数组包含你的ActivityType常量对应的字符串(需为反向域名格式,如com.yourcompany.vpn.connect):
<key>NSUserActivityTypes</key> <array> <string>com.yourcompany.vpn.connect</string> <string>com.yourcompany.vpn.disconnect</string> </array>
4. 优化后台操作逻辑,延长生命周期
处理NSUserActivity时,使用后台任务延长App生命周期,确保VPN操作完成:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void) -> Bool { var backgroundTask: UIBackgroundTaskIdentifier = .invalid backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "VPNSiriOperation") { UIApplication.shared.endBackgroundTask(backgroundTask) backgroundTask = .invalid } defer { if backgroundTask != .invalid { UIApplication.shared.endBackgroundTask(backgroundTask) } } if userActivity.activityType == Constants.connectVPNSiriActivityType { guard let status = packetTunnelManager.status, status == .disconnected else { return true } Task { do { try await packetTunnelManager.start() } catch { print("Siri触发VPN连接失败: \(error.localizedDescription)") } } } else if userActivity.activityType == Constants.disconnectVPNSiriActivityType { guard let status = packetTunnelManager.status, status == .connected else { return true } packetTunnelManager.stop() } return true }
5. 添加手动快捷方式入口(可选)
在App内提供手动添加Siri快捷方式的界面,让用户快速配置:
// 示例:设置页面按钮点击事件 @IBAction func addConnectShortcutTapped(_ sender: UIButton) { let activity = NSUserActivity(activityType: Constants.connectVPNSiriActivityType) activity.title = NSLocalizedString("siriShortcutConnectVPNTitle", comment: "") let shortcut = INShortcut(userActivity: activity) let vc = INUIAddVoiceShortcutViewController(shortcut: shortcut) vc.delegate = self present(vc, animated: true) } // 实现代理方法 extension SettingsViewController: INUIAddVoiceShortcutViewControllerDelegate { func addVoiceShortcutViewController(_ controller: INUIAddVoiceShortcutViewController, didFinishWith voiceShortcut: INVoiceShortcut?, error: Error?) { dismiss(animated: true) } func addVoiceShortcutViewControllerDidCancel(_ controller: INUIAddVoiceShortcutViewController) { dismiss(animated: true) } }
测试步骤
- 运行App,手动连接/断开VPN各一次,触发快捷方式捐赠
- 进入「设置」-「Siri与搜索」-「我的快捷方式」,确认VPN快捷方式已收录
- 打开YouTube,观察是否弹出Siri建议的VPN操作;或直接用语音触发(如“嘿Siri,连接VPN”)
- 若场景预测未自动触发,先手动添加快捷方式,再重复测试
内容的提问来源于stack exchange,提问作者максим мартынов
相关产品推荐
相关产品推荐

