Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用swift更改wifi DNS设置iOS_Ios_Swift_Networking_Dns_Settings - Fatal编程技术网

如何使用swift更改wifi DNS设置iOS

如何使用swift更改wifi DNS设置iOS,ios,swift,networking,dns,settings,Ios,Swift,Networking,Dns,Settings,我正在尽我最大的努力使它工作 我为我的客户提供了一个DNS服务器,有时我会向他们发送电子邮件来更改他们的DNS设置。但现在我想通过ios应用程序来实现这一点。 有没有办法让他们下载应用程序,然后点击应用程序上的一个按钮来改变它 我看了这个 但不确定 谢谢看看网络扩展课程。使用该类,您可以使用设置。可以将具有顶级域(即[“*.com”、“*.net”、“*.org”、“*.io”])的通配符列表作为域,并用作操作。将创建的所有TLD设置为域。然后创建并将其设置为与所有顶级域一起创建的,并将其设置

我正在尽我最大的努力使它工作

我为我的客户提供了一个DNS服务器,有时我会向他们发送电子邮件来更改他们的DNS设置。但现在我想通过ios应用程序来实现这一点。 有没有办法让他们下载应用程序,然后点击应用程序上的一个按钮来改变它

我看了这个

但不确定


谢谢

看看网络扩展课程。使用该类,您可以使用设置。可以将具有顶级域(即
[“*.com”、“*.net”、“*.org”、“*.io”]
)的通配符列表作为域,并用作操作。将创建的所有TLD设置为域。然后创建并将其设置为与所有顶级域一起创建的,并将其设置为。使用以这种方式创建的。如果如上所述创建and,则可以使用and属性打开和关闭and

下面是一个示例类,它正是这样做的

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]
    }
}
请注意,您必须打开网络扩展功能,并且会出现一个对话框,告诉用户您正在打开VPN连接,但当连接打开时,状态栏中不会出现[VPN]图标,因为我们没有设置VPN,只是使用按需规则

和我一样讨厌谷歌,也许你可以用它来设置DNS。。。
查看网络扩展类。使用该类,您可以使用设置。可以将具有顶级域(即
[“*.com”、“*.net”、“*.org”、“*.io”]
)的通配符列表作为域,并用作操作。将创建的所有TLD设置为域。然后创建并将其设置为与所有顶级域一起创建的,并将其设置为。使用以这种方式创建的。如果如上所述创建and,则可以使用and属性打开和关闭and

下面是一个示例类,它正是这样做的

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]
    }
}
请注意,您必须打开网络扩展功能,并且会出现一个对话框,告诉用户您正在打开VPN连接,但当连接打开时,状态栏中不会出现[VPN]图标,因为我们没有设置VPN,只是使用按需规则

和我一样讨厌谷歌,也许你可以用它来设置DNS。。。
请考虑建立一个DNStExpAgent扩展(网络扩展之一)来拦截设备上生成的所有DNS流量,并使用自定义/内部DNS服务器。请考虑建立一个DNStExpAgent扩展(网络扩展之一)来拦截设备上生成的所有DNS流量,并使用自定义/内部DNS服务器。p> 不,沙箱阻止(正确地)应用程序更改网络设置。这是怎么回事?是的,如果您正在为客户端创建VPN配置,您可以这样做,但不会影响设备的非VPN网络设置。请查看我的答案,这是有漏洞的,但有效。我看不到答案。删除了吗@PopmedicNo,沙盒阻止(非常正确地)应用程序更改网络设置。是的,如果您正在为客户端创建VPN配置,您可以这样做,但它不会影响设备的非VPN网络设置。请查看我的答案,它是有漏洞的,但有效。我没有看到答案。删除了吗@PopmedicThanks。什么是matchDomains规则来使用所有内容?不幸的是,没有办法为matchDomains使用通配符
*.
,所以我创建了一个数组(TLDList.tlds),其中包含所有顶级域的
.
,并将其传入。下面是我使用的要点:嘿,感谢您的代码,但我收到了以下错误:
vpn\u connect:save error-error-Domain-code=1“缺少协议或协议的类型无效”UserInfo={NSLocalizedDescription=缺少协议或协议的类型无效}
如何解决此问题?请注意,您必须打开网络扩展功能。你打开了吗?谢谢。什么是matchDomains规则来使用所有内容?不幸的是,没有办法为matchDomains使用通配符
*.
,所以我创建了一个数组(TLDList.tlds),其中包含所有顶级域的
.
,并将其传入。下面是我使用的要点:嘿,感谢您的代码,但我收到了以下错误:
vpn\u connect:save error-error-Domain-code=1“缺少协议或协议的类型无效”UserInfo={NSLocalizedDescription=缺少协议或协议的类型无效}
如何解决此问题?请注意,您必须打开网络扩展功能。你把它们打开了吗?