如何在 web-view swift 中设置代理?

如何在 web-view swift 中设置代理?

问题描述:

我正在尝试设置代理.以下是我的代码.

I am trying to set proxy. Following is my code.

func startLoading() {
        let proxy_server: CFString = "abc.somecompanyname.com" // proxy server
        let proxy_port: CFNumber = 1234 // port

        //"request" is your NSURLRequest
        let url: NSURL = request.URL!
        let urlString: String = url.absoluteString
        let urlStringRef: CFString = (urlString as CFString)
        let myURL: CFURLRef = CFURLCreateWithString(kCFAllocatorDefault, urlStringRef, nil)
        let requestMethod: CFString = "GET"//CFSTR("GET")
        // let myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET", myURL, kCFHTTPVersion1_1).takeRetainedValue()

        let myRequest: CFHTTPMessageRef = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1).takeRetainedValue()
        //CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, myURL, kCFHTTPVersion1_1)
        httpMessageRef = CFHTTPMessageCreateCopy(kCFAllocatorDefault, myRequest).takeRetainedValue()
        let myReadStream: CFReadStreamRef = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest).takeRetainedValue()//CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest)
        // You can add body, headers.... using core function api, CFNetwork.etc
        // below code is to set proxy from code if needs }
        var hostKey: NSString
        var portKey: NSString
        /*
         if (url.scheme.lowercaseString == "https") {
         hostKey = kCFStreamPropertyHTTPSProxyHost as NSString
         portKey = kCFStreamPropertyHTTPSProxyPort as NSString
         } else {
         hostKey = kCFStreamPropertyHTTPProxyHost as NSString
         portKey = kCFStreamPropertyHTTPProxyPort as NSString
         }
         */
        hostKey = kCFNetworkProxiesHTTPProxy as NSString
        portKey = kCFNetworkProxiesHTTPPort as NSString

        let proxyToUse: [NSObject : AnyObject] = [
            hostKey : proxy_server,
            portKey : proxy_port
        ]

        CFReadStreamSetProperty(myReadStream, kCFNetworkProxiesHTTPProxy, proxyToUse)

        CFReadStreamOpen(myReadStream)
    }

请告诉我设置代理的错误在哪里?

Please let me know where am I wrong to set the proxy?

CFReadStreamCreateForHTTPRequest 已被弃用,所以我应该使用什么来代替它.我对代理相关的东西还不成熟,所以请随时让我更深入地了解相同的东西,并建议我以更好的方式处理这个问题.

CFReadStreamCreateForHTTPRequest is deprecated so what should I use instead of that. I'm immature about proxy related stuff so please feel free to let me know more about the same in depth and suggest me to deal this in better way.

谢谢

创建自定义 url 协议处理程序后,请使用以下代码将其注册,以便您的协议优先于任何内置协议.

Once you created your custom url protocol handler, register it in using below code so your protocol will have priority over any of the built-in protocols.

import UIKit
import CoreFoundation

class ViewController: UIViewController {

    @IBOutlet weak var sWebViewOutlet : UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupViewDidLoad()
    }

    func setupViewDidLoad() {
        SpecialProtocol.registerSpecialProtocol()

        let url = NSURL(string: "http://www.google.com")
        let req = NSURLRequest(URL: url!)
        /* if this request will be handled by our special protocol... */
        //if ( [SpecialProtocol canInitWithRequest:request] ) {
        if SpecialProtocol.canInitWithRequest(req) {
            print("SpecialProtocol.canInitWithRequest(req)")
            self.sWebViewOutlet.loadRequest(req)
        }
        else {
            print("SpecialProtocol.cantInitWithRequest(req)")
        }
    }
}

NSURLProtocol 类的一个子类,它将处理所有 Web 协议,例如 HTTP、HTTPS、SSL 等.它提供了执行特定于协议的 URL 数据加载的基本结构.下面的代码,解决了我的问题……如果您发布比我更好的解决方案或答案,我将不胜感激.

A subclass of NSURLProtocol class that will handle all web protocols such as HTTP, HTTPS, SSL etc. It provides the basic structure for performing protocol-specific loading of URL data. Below code, solved my problem... I'll appreciate if you post a better solution or answer than mine.

import UIKit
import CoreFoundation

class SpecialProtocol: NSURLProtocol, NSURLSessionDataDelegate, NSURLSessionTaskDelegate {
//var httpMessageRef: CFHTTPMessage;()
    var httpMessageRef: CFHTTPMessage?

    class func registerSpecialProtocol() {
        var inited: Bool = false
        if !inited {
            NSURLProtocol.registerClass(SpecialProtocol.self)
            inited = true
        }
    }


    private var dataTask:NSURLSessionDataTask?
    private var urlResponse:NSURLResponse?
    private var receivedData:NSMutableData?

    class var CustomKey:String {
        return "myCustomKey"
    }

    // MARK: NSURLProtocol

    override class func canInitWithRequest(request: NSURLRequest) -> Bool {
        if (NSURLProtocol.propertyForKey(SpecialProtocol.CustomKey, inRequest: request) != nil) {
            return false
        }

        return true
    }

    override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
        return request
    }

    override func startLoading() {

        let newRequest = self.request.mutableCopy() as! NSMutableURLRequest

        NSURLProtocol.setProperty("true", forKey: SpecialProtocol.CustomKey, inRequest: newRequest)

        let defaultConfigObj = customizeEphemeralSessionConfiguration()//NSURLSessionConfiguration.defaultSessionConfiguration()
        let defaultSession = NSURLSession(configuration: defaultConfigObj, delegate: self, delegateQueue: nil)

        self.dataTask = defaultSession.dataTaskWithRequest(newRequest)
        self.dataTask!.resume()

    }

    func customizeEphemeralSessionConfiguration() -> NSURLSessionConfiguration {
        let proxy_server: CFString = "YourProxyServer" // proxy server

        let proxy_port: CFNumber = 1234 // your port


        let hostKey: NSString = kCFNetworkProxiesHTTPProxy as NSString
        let portKey: NSString = kCFNetworkProxiesHTTPPort as NSString

        let proxyDict:[String:AnyObject] = [kCFNetworkProxiesHTTPEnable as String: true, hostKey as String:proxy_server, portKey as String: proxy_port]

        let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        config.connectionProxyDictionary = proxyDict as [NSObject : AnyObject]

        return config
    }


    override func stopLoading() {
        self.dataTask?.cancel()
        self.dataTask       = nil
        self.receivedData   = nil
        self.urlResponse    = nil
    }

    // MARK: NSURLSessionDataDelegate

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask,
                    didReceiveResponse response: NSURLResponse,
                                       completionHandler: (NSURLSessionResponseDisposition) -> Void) {

        self.client?.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: .NotAllowed)

        self.urlResponse = response
        self.receivedData = NSMutableData()

        completionHandler(.Allow)
    }

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
        self.client?.URLProtocol(self, didLoadData: data)

        self.receivedData?.appendData(data)
    }

    // MARK: NSURLSessionTaskDelegate

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        if error != nil && error!.code != NSURLErrorCancelled {
            self.client?.URLProtocol(self, didFailWithError: error!)
        } else {
            saveCachedResponse()
            self.client?.URLProtocolDidFinishLoading(self)
        }
    }

    // MARK: Private methods

    /**
     Do whatever with the data here
     */
    func saveCachedResponse () {
        let timeStamp = NSDate()
        let urlString = self.request.URL?.absoluteString
        let dataString = NSString(data: self.receivedData!, encoding: NSUTF8StringEncoding) as NSString?
        print("TimeStamp:\(timeStamp)\nURL: \(urlString)\n\nDATA:\(dataString)\n\n")
    }

}