iOS端重启App后调用stopVPNTunnel无法断开VPN连接问题求助
问题根因
App重启后你持有的NEVPNManager实例未同步系统中实际的VPN配置状态,直接调用stopVPNTunnel()会因为实例和系统当前运行的VPN隧道不关联导致操作无效。
可行解决方案
- 所有VPN操作(连接、断开)执行前必须先调用
loadFromPreferences()同步系统状态,断开操作要放在加载完成的回调中执行
修改后的disconnectVPN代码:
public func disconnectVPN() ->Void { Log.d(message: "Disconnect VPN Called") Log.d(message: "Log Disconnect VPN Called") // 先同步系统VPN配置 self.vpnManager.loadFromPreferences { error in if let error = error { Log.d(message: "加载VPN配置失败: \(error.localizedDescription)") return } print("vpnManager:disconnectVPN \(self.vpnManager.connection) ") // 配置加载完成后再执行断开操作 self.vpnManager.connection.stopVPNTunnel() } }
- 避免重复注册
NEVPNStatusDidChange通知:你当前每次调用connectVPN都会新增一个通知监听,会导致同一次状态变更触发多次回调,建议仅在vpnManager初始化完成后注册一次通知,或者注册前先移除旧的监听
优化后的connectVPN通知注册部分:
public func connectVPN() { Log.d(message: "connectVPN") NSLog("ConnectVPN") self.vpnManager.loadFromPreferences(completionHandler: self.vpnLoadHandler) // 先移除旧的监听,避免重复注册 NotificationCenter.default.removeObserver(self, name: NSNotification.Name.NEVPNStatusDidChange, object: nil) NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: nil , queue: nil) { notification in let nevpnconn = notification.object as! NEVPNConnection let status = nevpnconn.status self.vpnDelegate?.checkNES(status: status) } }
- App重启后如果需要操作VPN,不要复用之前缓存的
vpnManager状态,建议在App进入前台、首次需要操作VPN前主动调用一次loadFromPreferences()同步最新状态
验证步骤
- 连接VPN成功后杀掉App进程
- 重新打开App,直接触发断开操作,查看是否能正常停止VPN隧道
- 检查系统设置中的VPN状态是否同步变为未连接
内容的提问来源于stack exchange,提问作者Wasi Sadman
相关产品推荐
相关产品推荐

