如何使用Alamofire 4和Swift 3的代理服务器

时间:2017-03-06 03:07:23

标签: ios swift alamofire

请不要标记为重复,我无法使用现有主题解决我的问题。

我正在尝试将我的代理用于需要指定IP的API请求。 为了调试我的问题,我正在从Web服务请求IP。

这是我目前的代码:

import UIKit
import Alamofire

class ViewController: UIViewController {

    var requestManager = Alamofire.SessionManager.default

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)

        var proxyConfiguration = [NSObject: AnyObject]()
        proxyConfiguration[kCFNetworkProxiesHTTPProxy] = "http://xxx@eu-west-static-01.quotaguard.com" as AnyObject?
        proxyConfiguration[kCFNetworkProxiesHTTPPort] = "9293" as AnyObject?
        proxyConfiguration[kCFNetworkProxiesHTTPEnable] = 1 as AnyObject?

        let cfg = Alamofire.SessionManager.default.session.configuration
        cfg.connectionProxyDictionary = proxyConfiguration

        let ip = URL(string: "https://api.ipify.org?format=json")

        requestManager = Alamofire.SessionManager(configuration: cfg)
        requestManager.request(ip!).response { response in
            print("Request: \(response.request)")
            print("Response: \(response.response)")
            print("Error: \(response.error)")

            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)")
            }
        }
    }
}

问题:无论是否有proxyConfiguration,响应的IP都是相同的。非常感谢任何帮助。

PS:使用的物理设备。

3 个答案:

答案 0 :(得分:10)

我认为工作(应该被弃用)键是:

kCFStreamPropertyHTTPSProxyHost
kCFStreamPropertyHTTPSProxyPort

你可以尝试这段代码吗?

import UIKit
import Alamofire

class ViewController: UIViewController {

    var requestManager = Alamofire.SessionManager.default

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)

         var proxyConfiguration = [NSObject: AnyObject]()
         proxyConfiguration[kCFNetworkProxiesHTTPProxy] = "eu-west-static-01.quotaguard.com" as AnyObject?
         proxyConfiguration[kCFNetworkProxiesHTTPPort] = "9293" as AnyObject?
         proxyConfiguration[kCFNetworkProxiesHTTPEnable] = 1 as AnyObject?
         proxyConfiguration[kCFStreamPropertyHTTPSProxyHost as String] = "eu-west-static-01.quotaguard.com"
         proxyConfiguration[kCFStreamPropertyHTTPSProxyPort as String] = 9293
         proxyConfiguration[kCFProxyUsernameKey as String] = xxx
         //proxyConfiguration[kCFProxyPasswordKey as String] = "pwd if any"
        let cfg = Alamofire.SessionManager.default.session.configuration
        cfg.connectionProxyDictionary = proxyConfiguration

        let ip = URL(string: "https://api.ipify.org?format=json")

        requestManager = Alamofire.SessionManager(configuration: cfg)
        requestManager.request(ip!).response { response in
            print("Request: \(response.request)")
            print("Response: \(response.response)")
            print("Error: \(response.error)")

            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)")
            }
        }
    }
}

另外,请确保您的代理服务器配置为处理https请求。

注意:这些密钥可能会发出deprecated警告但密钥仍然有效(请参阅https://forums.developer.apple.com/thread/19356#131446

注意:我发布了相同的答案here。在这里发布的内容与此处适用的相同。 Alamofire使用相同的URLSessionConfiguration

答案 1 :(得分:3)

根据Manishg的回答,我使用以下内容来避免警告

let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders

var proxyConfiguration = [String: AnyObject]()
proxyConfiguration.updateValue(1 as AnyObject, forKey: "HTTPEnable")
proxyConfiguration.updateValue("eu-west-static-01.quotaguard.com" as AnyObject, forKey: "HTTPProxy")
proxyConfiguration.updateValue(9293 as AnyObject, forKey: "HTTPPort")
proxyConfiguration.updateValue(1 as AnyObject, forKey: "HTTPSEnable")
proxyConfiguration.updateValue("eu-west-static-01.quotaguard.com" as AnyObject, forKey: "HTTPSProxy")
proxyConfiguration.updateValue(9293 as AnyObject, forKey: "HTTPSPort")
configuration.connectionProxyDictionary = proxyConfiguration

sharedManager = Alamofire.SessionManager(configuration: configuration)

https常量已被弃用,可以随时删除。通过使用字符串值,代码可能会中断,但不会崩溃

答案 2 :(得分:0)

基于 Fraser 个答案和 How can I get my external IP address in a shell script? 个问题

详情

  • Swift 5.3
  • 版本 12.4 (12D4e)
  • 阿拉莫火 5

完整样本

<块引用>

NetworkService.swift

import Foundation
import Alamofire

struct Proxy {
    let host: String
    let port: Int
}

class NetworkService {
    
    // Pick free some proxies from here https://free-proxy-list.net if current do not work
    private let listOfProxies = [
        Proxy(host: "67.43.224.131", port: 3128), // Canada
        Proxy(host: "167.172.180.40", port: 44129), // Germany
        Proxy(host: "185.236.202.205", port: 3128), // Austria
    ]
    
    private(set) var session: Session!
    private var proxy: Proxy?
    init () { resetSessionManager() }

    func setRandomProxy() {
        self.proxy = listOfProxies.randomElement()
        resetSessionManager()
    }

    private
    func resetSessionManager() {
        let config = Session.default.session.configuration
        if let proxy = proxy {
            config.connectionProxyDictionary = [
                "HTTPEnable": 1,
                "HTTPProxy": proxy.host ,
                "HTTPPort": proxy.port,
                "HTTPSEnable": true,
                "HTTPSProxy": proxy.host,
                "HTTPSPort": proxy.port
            ]
        } else {
            config.connectionProxyDictionary = [:]
        }
        self.session = Session(configuration: config)
    }
    
    func request(url: URLConvertible,
                 method: Alamofire.HTTPMethod = .get,
                 parameters: Parameters? = nil,
                 encoding: ParameterEncoding = URLEncoding.default,
                 headers: HTTPHeaders? = nil,
                 completion: @escaping (Result<Data, Error>) -> Void) {
        let request = session.request(url, method: method,
                                      parameters: parameters,
                                      encoding: encoding,
                                      headers: headers)
        request.response { respionse in
            if let error = respionse.error {
                completion(.failure(error))
            } else if let data = respionse.data {
                completion(.success(data))
            }
        }
    }
    func request<T: Decodable>(url: URLConvertible,
                               method: Alamofire.HTTPMethod = .get,
                               parameters: Parameters? = nil,
                               encoding: ParameterEncoding = URLEncoding.default,
                               headers: HTTPHeaders? = nil,
                               completion: @escaping (Result<T, Error>) -> Void) {
        request(url: url, method: method,
                parameters: parameters,
                encoding: encoding,
                headers: headers) { result in
            switch result {
            case .failure(let error): completion(.failure(error))
            case .success(let data):
                do {
                    let object = try JSONDecoder().decode(T.self, from: data)
                    completion(.success(object))
                } catch let error {
                    completion(.failure(error))
                }
            }
        }
    }
}
<块引用>

GeoIP.swift

import Foundation

struct GeoIP: Codable {
    let lat: Double
    let lon: Double
    let zip: String
    let query: String
    let city: String
    let regionName: String
    let country: String
    let timezone: String
}

extension GeoIP: CustomStringConvertible {
    var description: String {
        "\(city), \(regionName), \(country), \(zip)\nIP:\(query)\nCoordinates:(\(lat),\(lon))\nTimezone: \(timezone)"
    }
}
<块引用>

ViewController.swift

class ViewController: UIViewController {
    
    private let networkService = NetworkService()
    private weak var button: UIButton!
    private weak var activityIndicatorView: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: view.frame)
        button.setTitleColor(.blue, for: .normal)
        button.setTitle("Pick random proxy and get my ip", for: .normal)
        button.addTarget(self, action: #selector(buttonTouchedUpInside(source:)), for: .touchUpInside)
        view.addSubview(button)
        self.button = button
        
        let activityIndicatorView = UIActivityIndicatorView(frame: view.frame)
        view.addSubview(activityIndicatorView)
        self.activityIndicatorView = activityIndicatorView
    }
    
    @objc func buttonTouchedUpInside(source: UIButton) {
        source.isHidden = true
        activityIndicatorView.startAnimating()
        networkService.setRandomProxy()
        showMyGeoIpInfo()
    }
}

extension ViewController {
    
    private func showMyGeoIpInfo() {
        let group = DispatchGroup()
        group.enter()
        group.enter()
        group.enter()
        var httpIP: String?
        var httpsIP: String?
        var geoIp: GeoIP?
        group.notify(queue: .main) { [weak self] in
            guard let self = self else { return }
            let _httpIP = httpIP ?? "nil"
            let _httpsIP = httpsIP ?? "nil"
            let geoIpDescription = geoIp?.description ?? "nil"
            let message = "HTTP request IP: \(_httpIP)\nHTTPS request IP: \(_httpsIP)\n GeoIP: \(geoIpDescription)"
            self.showAlert(title: "GeoIP", message: message)
            self.button.isHidden = false
            self.activityIndicatorView.stopAnimating()
        }
        
        // Get my IP on http request
        getSimpleText(from: "http://ipecho.net/plain") { text in
            httpIP = text
            group.leave()
        }
        
        // Get my IP on https request
        getSimpleText(from: "https://icanhazip.com") { text in
            httpsIP = text
            group.leave()
        }
        

        // Get my GeoIp info
        networkService.request(url: "http://ip-api.com/json/",
                               encoding: JSONEncoding.default) { (response: Result<GeoIP, Error>) in
            defer { group.leave() }
            switch response {
            case .failure(let error): print("Error: \(error)")
            case .success(let value): geoIp = value
            }
        }
    }
    
    private func getSimpleText(from url: String, completion: @escaping (String?) -> Void) {
        networkService.request(url: "https://icanhazip.com") { result in
            switch result {
            case .failure(let error):
                print("Error: \(error)")
                completion(nil)
            case .success(let data):
                let text = String(decoding: data, as: UTF8.self).trimmingCharacters(in: .whitespacesAndNewlines)
                completion(text)
            }
        }
    }

    private func showAlert(title: String?, message: String?) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
        present(alertController, animated: true, completion: nil)
    }
}

截图

enter image description here enter image description here enter image description here

相关问题