How to set Proxy in web-view swift?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-23 04:53:32

问题


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 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.

Thanks


回答1:


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)")
        }
    }
}

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")
    }

}


来源:https://stackoverflow.com/questions/38968040/how-to-set-proxy-in-web-view-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!