如何在iOS中以编程方式更改/添加用于已连接WiFi的DNS服务器?

Asi*_*aza 4 dns ios

我想以编程方式为我的iPhone设备的已连接WiFi更改/添加DNS服务器吗?

Google公用DNS IP地址(IPv4)如下:8.8.8.8 8.8.4.4

我想以编程方式更改/添加它,如附件屏幕截图所示。

请帮忙。我可以在Objective-c或Swift中管理它。在Objective-c中对我来说会更有用。提前致谢。

连接的Wi-Fi虚拟/旧DNS服务器:-

在此处输入图片说明

连接的Wi-Fi所需的DNS服务器:-

在此处输入图片说明

Pop*_*dic 5

查看网络扩展类。随着NETunnelProviderManager类,你可以设置onDemandRulesNEEvaluateConnectionRule。该NEEvaluateConnectionRule构造可以采取与顶级域(即通配符的列表["*.com", "*.net", "*.org", "*.io"])的域,并使用NEEvaluateConnectionRuleAction.connectIfNeeded作为动作。设置将所有tlds作为域创建的NEEvaluateConnectionRuleonDemandRules。然后创建一个NEOnDemandRuleEvaluateConnection并将其 connectionRules设置为NEEvaluateConnectionRule使用所有顶级域创建,并将其interfaceTypeMatch设置为NEOnDemandRuleInterfaceType.any。设置NETunnelProviderManager.onDemandRulesNEOnDemandRuleEvaluateConnection这种方式创建。如果创建了NETunnelProviderManager并如上所述进行加载保存,则可以使用NETunnelProviderManager.isEnabledNETunnelProviderManager.isOnDemandEnabled属性将其打开和关闭。

这是一个完全做到这一点的示例类。

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]
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您必须打开“网络扩展”功能,并且会出现一个对话框,告诉用户您正在打开VPN连接,但是当连接为“打开”时,状态栏中将没有[VPN]图标。之所以开启,是因为我们没有设置VPN,只是使用了随需应变的规则。

这是我使用的TLDList类。

像我一样讨厌Google,也许将其用于您设置的DNS ... Quad9