Прокси в Swift
Swift — основной язык для разработки iOS и macOS приложений. Работа с прокси в Swift осуществляется через URLSession (высокоуровневый API), Network framework (низкоуровневый) и системные настройки.
URLSession с прокси
Настройка через URLSessionConfiguration
import Foundation
let config = URLSessionConfiguration.default
// Настройка 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()
SOCKS прокси
config.connectionProxyDictionary = [
kCFStreamPropertySOCKSProxyHost: "proxy_ip",
kCFStreamPropertySOCKSProxyPort: 1080,
kCFStreamPropertySOCKSVersion: kCFStreamSocketSOCKSVersion5
]
С аутентификацией
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "proxy_ip",
kCFNetworkProxiesHTTPPort: 8080,
kCFProxyUsernameKey: "username",
kCFProxyPasswordKey: "password"
]
Системные настройки прокси
Автоматическое использование
По умолчанию URLSession использует системные прокси:
let config = URLSessionConfiguration.default
// По умолчанию использует системные прокси
let session = URLSession(configuration: config)
Если пользователь настроил прокси в системных настройках iOS/macOS, URLSession автоматически будет их использовать.
PAC-файл
config.connectionProxyDictionary = [
kCFNetworkProxiesProxyAutoConfigEnable: true,
kCFNetworkProxiesProxyAutoConfigURLString: "http://example.com/proxy.pac"
]
Обработка Proxy Authentication Challenge
Когда прокси требует аутентификацию, URLSession вызывает 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)
Network Framework (NWConnection)
Для низкоуровневой работы с сетью в iOS 12+ / macOS 10.14+:
import Network
let proxyConfig = NWProtocolTLS.Options()
let params = NWParameters.tls
// Настройка прокси через NWEndpoint
let proxyEndpoint = NWEndpoint.hostPort(
host: NWEndpoint.Host("proxy_ip"),
port: NWEndpoint.Port(rawValue: 8080)!
)
// Создание подключения
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 с прокси
Alamofire — популярная Swift HTTP-библиотека:
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)
}
}
iOS-специфика
VPN и прокси в iOS
iOS позволяет настроить прокси через:
1. Системные настройки (Settings → Wi-Fi → HTTP Proxy)
2. MDM-профили
3. NEProxySettings (Network Extension framework)
Network Extension
Для создания полноценного прокси-приложения на iOS используйте NETransparentProxyProvider:
import NetworkExtension
class ProxyProvider: NETransparentProxyProvider {
override func startProxy(options: [String: Any]?, completionHandler: @escaping (Error?) -> Void) {
// Настройка прокси
completionHandler(nil)
}
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
// Обработка нового соединения
return true
}
}
Это требует entitlement от Apple и подходит для 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) ?? ""
}
// Использование
Task {
let ip = try await fetchViaProxy()
print(ip)
}
Заключение
Swift предоставляет гибкие инструменты для работы с прокси: URLSession для высокоуровневых задач, Network framework для низкоуровневого контроля, и Network Extension для создания прокси-приложений. Для большинства задач URLSession с connectionProxyDictionary — оптимальный выбор.