2017-03-06 69 views
13

對於API請求我試圖使用代理設置URLSession。出於測試目的,我使用公共代理服務器和響應IP的API。如何在Swift 3中使用帶Proxy的URLSession

func makeRequestViaUrlSessionProxy(_ url: String, completion: @escaping (_ result: String?) ->()) { 

    let request = URLRequest(url: URL(string: url)!) 

    let config = URLSessionConfiguration.default 
    config.requestCachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData 
    config.connectionProxyDictionary = [AnyHashable: Any]() 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPEnable as String] = 1 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPProxy as String] = "142.54.173.19" 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPPort as String] = 8888 

    let session = URLSession.init(configuration: config, delegate: nil, delegateQueue: OperationQueue.current) 

    let task = session.dataTask(with: request) { 
     (data: Data?, response: URLResponse?, error: Error?) in 
     if error != nil { 
      NSLog("Client-side error in request to \(url): \(error)") 
      completion(nil) 
      return 
     } 

     if data == nil { 
      NSLog("Data from request to \(url) is nil") 
      completion(nil) 
      return 
     } 

     let httpResponse = response as? HTTPURLResponse 
     if httpResponse?.statusCode != 200 { 
      NSLog("Server-side error in request to \(url): \(httpResponse)") 
      completion(nil) 
      return 
     } 

     let encodingName = response?.textEncodingName != nil ? response?.textEncodingName : "utf-8" 
     let encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding(encodingName as CFString!)) 
     let stringData = String(data: data!, encoding: String.Encoding(rawValue: UInt(encoding))) 
     session.invalidateAndCancel() 
     completion(stringData) 
    } 
    task.resume() 
} 

通過調用:

override func viewDidLoad() { 
    super.viewDidLoad() 
    makeRequestViaUrlSessionProxy("https://api.ipify.org?format=json") { string in 
     print(string) 
    } 
} 

這似乎是config完全被忽略,因爲即使有由代理IP,則迴應IP始終是實際的設備IP

任何幫助是高度讚賞。

編輯:由用戶hasan83建議,採取「HTTPS鍵」似乎不是一個選項。

enter image description here enter image description here

+0

你好,142.54.173.19這個IP是哪個IP地址,路由器或其他。 ? –

回答

7

我認爲工作(咋辦將被棄用)鑰匙是:

kCFStreamPropertyHTTPSProxyHost 
kCFStreamPropertyHTTPSProxyPort 

你可以試試這段代碼嗎?

func makeRequestViaUrlSessionProxy(_ url: String, completion: @escaping (_ result: String?) ->()) { 

    let request = URLRequest(url: URL(string: url)!) 

    let config = URLSessionConfiguration.default 
    config.requestCachePolicy = URLRequest.CachePolicy.reloadIgnoringLocalCacheData 
    config.connectionProxyDictionary = [AnyHashable: Any]() 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPEnable as String] = 1 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPProxy as String] = "142.54.173.19" 
    config.connectionProxyDictionary?[kCFNetworkProxiesHTTPPort as String] = 8888 
    config.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyHost as String] = "142.54.173.19" 
    config.connectionProxyDictionary?[kCFStreamPropertyHTTPSProxyPort as String] = 8888 

    let session = URLSession.init(configuration: config, delegate: nil, delegateQueue: OperationQueue.current) 

    let task = session.dataTask(with: request) { 
     (data: Data?, response: URLResponse?, error: Error?) in 
     if error != nil { 
      NSLog("Client-side error in request to \(url): \(error)") 
      completion(nil) 
      return 
     } 

     if data == nil { 
      NSLog("Data from request to \(url) is nil") 
      completion(nil) 
      return 
     } 

     let httpResponse = response as? HTTPURLResponse 
     if httpResponse?.statusCode != 200 { 
      NSLog("Server-side error in request to \(url): \(httpResponse)") 
      completion(nil) 
      return 
     } 

     let encodingName = response?.textEncodingName != nil ? response?.textEncodingName : "utf-8" 
     let encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding(encodingName as CFString!)) 
     let stringData = String(data: data!, encoding: String.Encoding(rawValue: UInt(encoding))) 
     session.invalidateAndCancel() 
     completion(stringData) 
    } 
    task.resume() 
} 

此外請確保您的代理服務器配置爲處理https請求。

注:它可能給deprecated警告那些鍵,但鍵仍在工作(見https://forums.developer.apple.com/thread/19356#131446

+0

似乎工作。明天會有更多的測試,但似乎是這樣。 –

+0

據我目前的研究,你的配置應該在這裏工作,所以請隨時嘗試,如果有效,也請在這裏回答:http://stackoverflow.com/questions/42616908/how-to-use- a-proxy-server-with-alamofire-4-and-swift-3 –

+0

是的,同樣的配置應該與alamofire會話管理器一起工作,因爲它們也使用URLSessionConfiguration.default。感謝您的高舉。我會在那裏發佈答案。 – manishg

1

我不知道這是否有意義。但是,在兩個不同模式設定按鍵的位置:

  1. HTTP
  2. HTTPS

代理鍵:

// http proxy keys 
kCFNetworkProxiesHTTPEnable 
kCFNetworkProxiesHTTPProxy 
kCFNetworkProxiesHTTPPort 

// https proxy keys 
kCFNetworkProxiesHTTPSEnable 
kCFNetworkProxiesHTTPSProxy 
kCFNetworkProxiesHTTPSPort 
+0

我有複製/粘貼您建議的HTTPS值,但對於所有我得到「xy不可用」。此外,HTTP「S」一個不適用於自動填寫 –

+0

請參閱添加的屏幕 –

相關問題