iOS拦截我应用的所有网络流量?

Gui*_*uig 6 proxy networking ios

我想为来自我的应用的所有网络电话添加代理.就像是

func intercept(request: URLRequest) {
  if isOk(request) {
    return // the request continues as normally
  } else if isIntercepted(request) {
    let res = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "HTTP/2", headerFields: ["Content-Type": "application/json"])
    res.value = "{\"ok\":true}" // not that exactly work, but you get the idea
    request.end(res)
  } else {
    let res = HTTPURLResponse(url: url, statusCode: 401, httpVersion: "HTTP/2")
    res.value = "forbidden"
    request.end(res)
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望它适用于来自我的应用的所有来电.即我的代码和我正在使用的所有库和框架.可能吗?

我发现了有关阅读其他应用程序流量(不可能)的问题,并设置了代码从我的代码开始调用.我想进一步讨论1)会自动应用于所有流量的事情,2)包括来自第三方的流量

Bru*_*ipe 8

这是URLProtocol班上的工作.

来自Apple的文档:

NSURLProtocol对象处理特定于协议的URL数据的加载.NSURLProtocol类本身是一个抽象类,它提供了使用特定URL方案处理URL的基础结构.您可以为应用支持的任何自定义协议或URL方案创建子类.

您需要实现自己的子类URLProtocol并将其注册到应用程序以供其使用.此后,从App初始化的所有连接都将使用该协议,您将能够处理/阻止您想要的任何请求.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
    guard URLProtocol.registerClass(MyURLProtocol.self) else
    {
        abort()
    }

    return true
}
Run Code Online (Sandbox Code Playgroud)

此外,如果您正在使用URLSession(并且您应该!),那么您还必须通过会话配置注册您的课程:

func getURLSessionConfiguration() -> URLSessionConfiguration
{
    let configuration = URLSessionConfiguration.default

    configuration.protocolClasses = [
        MyURLProtocol.self
    ]

    return configuration
}

let session = URLSession(configuration: getURLSessionConfiguration())
Run Code Online (Sandbox Code Playgroud)

然后,您可以从子类的startLoading()方法管理要阻止的任何内容URLProtocol:

override func startLoading()
{
    if !self.isOK()
    {
        let error = NSError(domain: "GuardURLProtocol", code: 10, userInfo: [NSLocalizedDescriptionKey: "Connection denied by guard"])
        self.client?.urlProtocol(self, didFailWithError: error)
    }
    else if let task = self.task
    {
        task.resume()
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须实现更多方法,并且应该阅读Apple文档.

但作为一个小发明(和我自己的练习),我已经编写了一个通用的阻止协议,你应该检查一下它是如何工作的.在GuardURLProtocol.swift文件的底部有一个示例子类(BlockFPTURLSession),其中所有FTP请求都被模式阻止.

如果您使用上面链接的类,并尝试打开FTP连接,您将看到以下错误:

2017-02-16 23:09:45.846 URLProtocol[83111:7456862] Error: Error Domain=GuardURLProtocol Code=10 "Connection denied by guard" UserInfo={NSLocalizedDescription=Connection denied by guard}
Run Code Online (Sandbox Code Playgroud)

玩得开心!