Usando proxies em Swift
Proxies em Swift
Swift é a principal linguagem para desenvolver aplicativos iOS e macOS. O trabalho com proxies em Swift é feito por meio do URLSession (uma API de alto nível), do framework Network (baixo nível) e das configurações do sistema.
URLSession com proxies
Configuração via URLSessionConfiguration
import Foundation
let config = URLSessionConfiguration.default
// Configuração de proxy HTTP
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "proxy_ip",
kCFNetworkProxiesHTTPPort: 8080,
kCFNetworkProxiesHTTPSEnable: true,
kCFNetworkProxiesHTTPSProxy: "proxy_ip",
kCFNetworkProxiesHTTPSPort: 8080
]
let session = URLSession(configuration: config)
let url = URL(string: "https://httpbin.org/ip")!
let task = session.dataTask(with: url) { data, response, error in
if let data = data, let body = String(data: data, encoding: .utf8) {
print(body)
}
}
task.resume()
Proxy SOCKS
config.connectionProxyDictionary = [
kCFStreamPropertySOCKSProxyHost: "proxy_ip",
kCFStreamPropertySOCKSProxyPort: 1080,
kCFStreamPropertySOCKSVersion: kCFStreamSocketSOCKSVersion5
]
Com autenticação
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "proxy_ip",
kCFNetworkProxiesHTTPPort: 8080,
kCFProxyUsernameKey: "username",
kCFProxyPasswordKey: "password"
]
Configurações de proxy do sistema
Uso automático
Por padrão, o URLSession usa os proxies do sistema:
let config = URLSessionConfiguration.default
// Usa os proxies do sistema por padrão
let session = URLSession(configuration: config)
Se o usuário tiver configurado proxies nas configurações de sistema do iOS/macOS, o URLSession os usará automaticamente.
Arquivo PAC
config.connectionProxyDictionary = [
kCFNetworkProxiesProxyAutoConfigEnable: true,
kCFNetworkProxiesProxyAutoConfigURLString: "http://example.com/proxy.pac"
]
Tratando o desafio de autenticação do proxy
Quando um proxy exige autenticação, o URLSession chama seu delegate:
class ProxyDelegate: NSObject, URLSessionDelegate {
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic
&& challenge.protectionSpace.isProxy {
let credential = URLCredential(
user: "username",
password: "password",
persistence: .forSession
)
completionHandler(.useCredential, credential)
} else {
completionHandler(.performDefaultHandling, nil)
}
}
}
let delegate = ProxyDelegate()
let session = URLSession(configuration: config, delegate: delegate, delegateQueue: nil)
Framework Network (NWConnection)
Para operações de rede de baixo nível no iOS 12+ / macOS 10.14+:
import Network
let proxyConfig = NWProtocolTLS.Options()
let params = NWParameters.tls
// Configuração de proxy via NWEndpoint
let proxyEndpoint = NWEndpoint.hostPort(
host: NWEndpoint.Host("proxy_ip"),
port: NWEndpoint.Port(rawValue: 8080)!
)
// Criando uma conexão
let connection = NWConnection(
host: "httpbin.org",
port: 443,
using: params
)
connection.stateUpdateHandler = { state in
switch state {
case .ready:
print("Connected")
case .failed(let error):
print("Failed: \(error)")
default:
break
}
}
connection.start(queue: .global())
Alamofire com proxies
Alamofire é uma biblioteca HTTP popular em Swift:
import Alamofire
let config = URLSessionConfiguration.default
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "proxy_ip",
kCFNetworkProxiesHTTPPort: 8080
]
let session = Session(configuration: config)
session.request("https://httpbin.org/ip").response { response in
if let data = response.data, let body = String(data: data, encoding: .utf8) {
print(body)
}
}
Particularidades do iOS
VPN e proxies no iOS
O iOS permite configurar proxy por meio de:
1. Configurações do sistema (Ajustes → Wi-Fi → Proxy HTTP)
2. Perfis MDM
3. NEProxySettings (framework Network Extension)
Network Extension
Para criar um aplicativo de proxy completo no iOS, use o NETransparentProxyProvider:
import NetworkExtension
class ProxyProvider: NETransparentProxyProvider {
override func startProxy(options: [String: Any]?, completionHandler: @escaping (Error?) -> Void) {
// Configuração do proxy
completionHandler(nil)
}
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
// Tratamento de uma nova conexão
return true
}
}
Isso exige um entitlement da Apple e é adequado para soluções Enterprise/MDM.
async/await (Swift 5.5+)
func fetchViaProxy() async throws -> String {
let config = URLSessionConfiguration.default
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "proxy_ip",
kCFNetworkProxiesHTTPPort: 8080
]
let session = URLSession(configuration: config)
let url = URL(string: "https://httpbin.org/ip")!
let (data, _) = try await session.data(from: url)
return String(data: data, encoding: .utf8) ?? ""
}
// Uso
Task {
let ip = try await fetchViaProxy()
print(ip)
}
Conclusão
O Swift oferece ferramentas flexíveis para trabalhar com proxies: URLSession para tarefas de alto nível, o framework Network para controle de baixo nível e o Network Extension para criar aplicativos de proxy. Para a maioria das tarefas, o URLSession com connectionProxyDictionary é a escolha ideal.
