问题描述
我想通过编程方式更改/添加用于iOS中iPhone设备的已连接WiFi的DNS服务器吗?
I want to change/add DNS server for connected WiFi of my iPhone device in iOS programmatically?
Google公共DNS IP地址(IPv4)如下:8.8.8.88.8.4.4
The Google Public DNS IP addresses (IPv4) are as follows:8.8.8.88.8.4.4
我希望以编程方式更改/添加它,就像所附屏幕截图中一样.
I want to change/add it as like in attached screenshot programmatically.
请帮助.我可以在Objective-c或Swift中管理它.在Objective-c中对我来说会更有用.预先感谢.
Please help. I can manage whether its in Objective-c or Swift. It will be more helpful for me in Objective-c.Thanks in advance.
已连接Wi-Fi的虚拟/旧DNS服务器:-
Dummy/Old DNS server of connected Wi-Fi:-
连接的Wi-Fi所需的DNS服务器:-
Required DNS server of connected Wi-Fi:-
推荐答案
查看网络扩展类.使用 NETunnelProviderManager 类,您可以设置 onDemandRules 和 NEEvaluateConnectionRule . NEEvaluateConnectionRule构造函数可以获取具有顶级域名的通配符列表,域(即 ["*.com","*.net","*.org","*.io"]
)作为域,并使用 NEEvaluateConnectionRuleAction.connectIfNeeded 作为操作.设置 onDemandRules 您以所有tlds为域创建的developer.apple.com/documentation/networkextension/neevaluateconnectionrule"rel =" nofollow noreferrer> NEEvaluateConnectionRule .然后创建一个 NEOnDemandRuleEvaluateConnection 并设置其 connectionRules 到使用所有顶级域创建的NEEvaluateConnectionRule ,并设置其 interfaceTypeMatch 到 NEOnDemandRuleInterfaceType.any 一个>.将 NETunnelProviderManager.onDemandRules 设置为 NEOnDemandRuleEvaluateConnection 是用这种方式创建的.如果您创建 NETunnelProviderManager 和加载它并保存,如上所述,然后您可以使用 NETunnelProviderManager.isEnabled 和 NETunnelProviderManager.isOnDemandEnabled 属性.
Look at the Network Extensions classes. With the NETunnelProviderManager class you can set the onDemandRules with a NEEvaluateConnectionRule. The NEEvaluateConnectionRule constructor can take a list of wildcard with top-level-domains (i.e. ["*.com", "*.net", "*.org", "*.io"]
) as the domains, and use NEEvaluateConnectionRuleAction.connectIfNeeded as the action. Set the onDemandRules of the NEEvaluateConnectionRule you create with all tlds as the domains. Then create a NEOnDemandRuleEvaluateConnection and set its connectionRules to the NEEvaluateConnectionRule created with all of the top-level-domains, and set its interfaceTypeMatch to NEOnDemandRuleInterfaceType.any. Set the NETunnelProviderManager.onDemandRules with a NEOnDemandRuleEvaluateConnection created this way. If you create a NETunnelProviderManagerand load it and save it as described above, you can then turn it on and off by using the NETunnelProviderManager.isEnabled and NETunnelProviderManager.isOnDemandEnabled properties.
这里是一个示例类,正是这样做的.
Here is an example class that does exactly that.
import Foundation
import NetworkExtension
public class 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.popmedic.vpntunnel.provider"
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]
}
}
请注意,您将必须打开Network Extensions功能,并且将显示一个对话框,告诉用户您正在打开VPN连接,但是在以下情况下,状态栏中不会显示[VPN]图标:因为我们没有设置VPN,只是使用了随需应变的规则,所以打开了连接.
Please note that you will have to turn the Network Extensions capabilities on and there will be a dialog presented telling the user that you are turning on a VPN connection, but you will not have the [VPN] icon in the status bar when the connection is turned on because we are not setting a vpn, just using the on demand rules.
和我一样讨厌Google,也许将其用于您设置的DNS ... Quad9
Hate Google as much as I do, maybe use this for the DNS you set...Quad9
这篇关于如何在iOS中以编程方式更改/添加用于已连接WiFi的DNS服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!