如何使用swift更改wifi DNS设置iOS
我正在尽我最大的努力使它工作 我为我的客户提供了一个DNS服务器,有时我会向他们发送电子邮件来更改他们的DNS设置。但现在我想通过ios应用程序来实现这一点。 有没有办法让他们下载应用程序,然后点击应用程序上的一个按钮来改变它 我看了这个 但不确定如何使用swift更改wifi DNS设置iOS,ios,swift,networking,dns,settings,Ios,Swift,Networking,Dns,Settings,我正在尽我最大的努力使它工作 我为我的客户提供了一个DNS服务器,有时我会向他们发送电子邮件来更改他们的DNS设置。但现在我想通过ios应用程序来实现这一点。 有没有办法让他们下载应用程序,然后点击应用程序上的一个按钮来改变它 我看了这个 但不确定 谢谢看看网络扩展课程。使用该类,您可以使用设置。可以将具有顶级域(即[“*.com”、“*.net”、“*.org”、“*.io”])的通配符列表作为域,并用作操作。将创建的所有TLD设置为域。然后创建并将其设置为与所有顶级域一起创建的,并将其设置
谢谢看看网络扩展课程。使用该类,您可以使用设置。可以将具有顶级域(即
[“*.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=缺少协议或协议的类型无效}
如何解决此问题?请注意,您必须打开网络扩展功能。你把它们打开了吗?