2017-08-04 135 views
9

在网络方面,DNS代理是iOS 11最大的特性之一,但他们没有提供关于它的大量文档或示例。还有一个talk,以及他们刚刚给出了有关DNS代理可能的说明。如何在iOS 11中使用NEDNSProxyProvider

我想创建一个工作示例,但直到现在才获得成功。因此,我创建了一个具有DNS代理权利的网络扩展,并添加了一个DNS代理提供程序。下面的代码:

class DNSProxyProvider: NEDNSProxyProvider { 
    let defaults = UserDefaults(suiteName: "group.com.securly.dnsProxy") 

    override init() { 
     NSLog("QNEDNSProxy.Provider: init") 
     super.init() 
     // +++ might want to set up KVO on `systemDNSSettings` 
    } 

    override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { 
     NSLog("QNEDNSProxy.Provider: start") 
     // self.defaults?.set("DidStart", forKey: "DidStart") 
     completionHandler(nil) 
    } 

    override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping() -> Void) { 
     NSLog("QNEDNSProxy.Provider: stop") 
     completionHandler() 
    } 

    override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { 
     NSLog("QNEDNSProxy.Provider: new flow (denied)") 
     // self.defaults?.set("DidHandleNewFlow", forKey: "DidHandleNewFlow") 
     return true 
    } 

} 

然后在AppDelegate中,我宣布一个NEDNSProxyManager并用它作为:

class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 
    let manager = NEDNSProxyManager.shared() 

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

     self.enable() 
     return true 
    } 

    private func enable() { 
     self.update { 
      self.manager.localizedDescription = "DNSProxySample" 
      let proto = NEDNSProxyProviderProtocol() 
      // proto.providerConfiguration = +++ 
      proto.providerBundleIdentifier = "com.securly.dnsProxy" 
      self.manager.providerProtocol = proto 
      self.manager.isEnabled = true 
     } 
    } 

    private func disable() { 
     self.update { 
      self.manager.isEnabled = false 
     } 
    } 

    private func update(_ body: @escaping() -> Void) { 
     self.manager.loadFromPreferences { (error) in 
      guard error == nil else { 
       NSLog("DNSProxySample.App: load error") 
       return 
      } 
      body() 
      self.manager.saveToPreferences { (error) in 
       guard error == nil else { 
        NSLog("DNSProxySample.App: save error") 
        return 
       } 
       NSLog("DNSProxySample.App: saved") 
      } 
     } 
    } 
} 

疑问/问题:

  1. 为什么不startProxyhandleNewFlow叫什么名字?设置有什么问题吗?
  2. 我如何提到自定义DNS地址?

回答

1

我设法通过系统触发DNSProxyProviderstartProxyhandleFlow。我的配置是这样的:

  1. 应享权利应用上的目标 enter image description here
  2. 在代理(DNSProxy)扩展

    应享权利 enter image description here 红线是类似于:group.com.xzy.project_name

  3. Info.plist扩展文件 enter image description here

  4. 的AppDelegate

    import UIKit 
    import NetworkExtension 
    
    @UIApplicationMain 
    class AppDelegate: UIResponder, UIApplicationDelegate { 
    
        var window: UIWindow? 
        let manager = NEDNSProxyManager.shared() 
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
         self.enable() 
         return true 
        } 
    
        private func enable() { 
         self.update { 
          self.manager.localizedDescription = "DNS" 
          let proto = NEDNSProxyProviderProtocol() 
          proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY" 
          self.manager.providerProtocol = proto 
          self.manager.isEnabled = true 
         } 
        } 
    
        private func disable() { 
         self.update { 
          self.manager.isEnabled = false 
         } 
        } 
    
        private func update(_ body: @escaping() -> Void) { 
         self.manager.loadFromPreferences { (error) in 
          guard error == nil else { 
           NSLog("DNS Test App: load error") 
           return 
          } 
          body() 
          self.manager.saveToPreferences { (error) in 
           guard error == nil else { 
            NSLog("DNS Test App: save error") 
            return 
           } 
           NSLog("DNS Test App: saved") 
          } 
         } 
        } 
    } 
    

不要忘记在这里变更包标识符proto.providerBundleIdentifier = "EXTENSION_BUNDLE_IDENTIFIER_WHICH_HAS_DNS_PROXY"

  • DNSProxyProvider

    import NetworkExtension 
    
    class DNSProxyProvider: NEDNSProxyProvider { 
    
        override init() { 
         NSLog("DNSProxyProvider: init") 
         super.init() 
        } 
    
        override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) { 
         NSLog("DNSProxyProvider: startProxy") 
         completionHandler(nil) 
        } 
    
        override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping() -> Void) { 
         NSLog("DNSProxyProvider: stopProxy") 
         completionHandler() 
        } 
    
        override func sleep(completionHandler: @escaping() -> Void) { 
         NSLog("DNSProxyProvider: sleep") 
         completionHandler() 
        } 
    
        override func wake() { 
         NSLog("DNSProxyProvider: wake") 
        } 
    
        override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool { 
         NSLog("DNSProxyProvider: handleFlow") 
         return false 
        } 
    
    } 
    
  • 作为最后一步在真实的iOS设备上运行应用程序。

  • 如果要在Mac上显示扩展日志,请打开Console.app

  • 调试扩展:您的主应用程序应该从运行菜单中选择。从Xcode的调试菜单中选择Attach to Process by PID or Name...,然后键入您的分机名称,按Attach按钮。看到Waiting to attach to EXTENSION_NAME on XYZ's iPhone后。在iOS设备上运行您的应用目标。

  • 相关问题