我已经配置了一个永远在线的 VPN,NEOnDemandRuleConnect
如果用户支付了订阅费用,我会从后端检索一些用户数据,例如到期日期。如果它过期,我想在不打开主应用程序的情况下停用 VPN,从网络扩展中进行。我使用每日计时器从后端检索数据,然后检查订阅是否已过期。然后我有一个功能,可以从系统设置应用程序加载 VPN 管理器,然后停用它,最后保存它。如果我不停用管理器,设备将无法连接,因为它是一个已配置为始终与NEOnDemandRule
. 功能或多或少会是这个
func stopProtection(completion: @escaping (Result<Void>) -> Void) {
NSLog("Called stopProtection")
NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
if let error = error {
NSLog("[SUBS] ERROR \(error)")
}
if let managers = managers {
if managers.count > 0 {
let index = managers.firstIndex(where: { $0.localizedDescription == Constants.vpnBundleId })
guard let index = index else {
completion(.error(ProtectionServiceError.noKidsVpnInstalled))
return
}
let myManager = managers[index]
myManager.loadFromPreferences(completionHandler: { (error) in
guard error == nil else {
completion(.error(ProtectionServiceError.errorStoppingTunnel))
return
}
// Deactivate the VPN and save it
myManager.isEnabled = false
myManager.saveToPreferences(completionHandler: { (error) in
guard error == nil else {
completion(.error(ProtectionServiceError.errorStoppingTunnel))
return
}
completion(.success(()))
})
})
} else {
completion(.error(ProtectionServiceError.errorStoppingTunnel))
}
}
}
}
所有这些代码和逻辑都在扩展中执行,并具有它所假设的所有限制。使用前面的函数我只会得到第NSLog
一句话Called stopProtection
,但它不会加载任何管理器。从主要目标调用它会起作用。我不知道我是否可以从扩展加载和修改管理器,或者这是另一种方式。