ios - 如何在 iOS Swift 中以编程方式配置 DNS 设置
问题描述
我正在尝试更改 DNS 设置以从我的代码中使用 Google DNS 服务器,我搜索了很多并从@user3769499 问题中找到了这个答案https://stackoverflow.com/a/50730387/4949756,但它不起作用为了我。这是我的代码:
import Foundation
import NetworkExtension
public class VPNConnect {
public static let shared: VPNConnect = VPNConnect()
private static let vpnDescription = "DNS OnDemand to GoogleDNS"
private static let vpnServerDescription = "OnDemand DNS to GoogleDNS"
public var manager:NETunnelProviderManager = NETunnelProviderManager()
public var dnsEndpoint1:String = "8.8.8.8"
public var dnsEndpoint2:String = "8.8.4.4"
public var connected:Bool {
get {
return self.manager.isOnDemandEnabled
}
set {
if newValue != self.connected {
update(
body: {
self.manager.isEnabled = newValue
self.manager.isOnDemandEnabled = newValue
},
complete: {
if newValue {
do {
try (self.manager.connection as? NETunnelProviderSession)?.startVPNTunnel(options: nil)
} catch let err as NSError {
NSLog("\(err.localizedDescription)")
}
} else {
(self.manager.connection as? NETunnelProviderSession)?.stopVPNTunnel()
}
}
)
}
}
}
public init() {
refreshManager()
}
public func refreshManager() -> Void {
NETunnelProviderManager.loadAllFromPreferences(completionHandler: { (managers, error) in
if nil == error {
if let managers = managers {
for manager in managers {
if manager.localizedDescription == VPNConnect.vpnDescription {
self.manager = manager
return
}
}
}
}
self.setPreferences()
})
}
private func update(body: @escaping ()->Void, complete: @escaping ()->Void) {
manager.loadFromPreferences { error in
if (error != nil) {
NSLog("Load error: \(String(describing: error?.localizedDescription))")
return
}
body()
self.manager.saveToPreferences { (error) in
if nil != error {
NSLog("vpn_connect: save error \(error!)")
} else {
complete()
}
}
}
}
private func setPreferences() {
self.manager.localizedDescription = VPNConnect.vpnDescription
let proto = NETunnelProviderProtocol()
// proto.providerBundleIdentifier = "com.DNSTest.NetworkExt"
proto.serverAddress = VPNConnect.vpnServerDescription
self.manager.protocolConfiguration = proto
// TLDList is a struct I created in its own swift file that has an array of all top level domains
let evaluationRule = NEEvaluateConnectionRule(matchDomains: TLDList.tlds,
andAction: NEEvaluateConnectionRuleAction.connectIfNeeded)
evaluationRule.useDNSServers = [self.dnsEndpoint1, self.dnsEndpoint2]
let onDemandRule = NEOnDemandRuleEvaluateConnection()
onDemandRule.connectionRules = [evaluationRule]
onDemandRule.interfaceTypeMatch = NEOnDemandRuleInterfaceType.any
self.manager.onDemandRules = [onDemandRule]
}
}
但现在,我有两个问题。
- 我应该把这门课放在哪里?它应该在主应用程序目标中,还是创建一个
NetworkExtension
目标并将此类放入其中? - 如果我必须制作
NetworkExtension
目标,我如何访问这个类来启用/禁用 DNS?
解决方案
推荐阅读
- terraform - 带有嵌入式函数的 Terraform 格式列表插值及其执行顺序
- javascript - 如何在 NestJS 中记录所有 Axios 外部 http 请求
- ajax - 我可以在 jquery-datatables 中使用 fetch api 吗?
- scala - 如何加快 sbt scala 在 docker 中的构建速度?
- angular - 编辑动态添加的值
- asp.net-mvc - 恶意实体在 asp.net 服务器上缓慢创建帐户
- javascript - 获取正则表达式的反义词
- angular - 如何使用 Service Worker 缓存所有页面
- ruby-on-rails - 验证失败:作业无效(Ruby on Rails)
- swt - 如何设置任务切换器图标文字?