Lion Lion - 1 year ago 230
iOS Question

How to set Proxy in web-view swift?

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

func startLoading() {
let proxy_server: CFString = "" // 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)


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

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.


Answer Source

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() {


    func setupViewDidLoad() {

        let url = NSURL(string: "")
        let req = NSURLRequest(URL: url!)
        /* if this request will be handled by our special protocol... */
        //if ( [SpecialProtocol canInitWithRequest:request] ) {
        if SpecialProtocol.canInitWithRequest(req) {
        else {

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 {
            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)


    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       = 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()


    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
        self.client?.URLProtocol(self, didLoadData: 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 {

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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download