问题
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