Route HTTP requests through KnoxProxy using Apple's built-in URLSession. Works on iOS, macOS, tvOS, and watchOS with no external dependencies.
Set up URLSessionConfiguration with KnoxProxy connection details.
let config = URLSessionConfiguration.default
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "gw.knoxproxy.com",
kCFNetworkProxiesHTTPPort: 7000,
kCFStreamPropertyHTTPSProxyHost: "gw.knoxproxy.com",
kCFStreamPropertyHTTPSProxyPort: 7000,
]Initialize a session with the proxy configuration.
let session = URLSession(configuration: config)Send a GET request through KnoxProxy.
let url = URL(string: "https://httpbin.org/ip")!
let task = session.dataTask(with: url) { data, response, error in
if let data = data {
print(String(data: data, encoding: .utf8) ?? "")
}
}
task.resume()Handle 407 challenges with a URLSessionDelegate.
class ProxyDelegate: NSObject, URLSessionDelegate {
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic {
let credential = URLCredential(
user: "USER",
password: "PASS",
persistence: .forSession
)
completionHandler(.useCredential, credential)
} else {
completionHandler(.performDefaultHandling, nil)
}
}
}
let session = URLSession(
configuration: config,
delegate: ProxyDelegate(),
delegateQueue: nil
)Target a specific country by changing the proxy username.
// In the delegate, change the username:
let credential = URLCredential(
user: "USER-country-gb",
password: "PASS",
persistence: .forSession
)Use modern Swift concurrency with the proxied session.
let (data, response) = try await session.data(from: url)
let httpResponse = response as! HTTPURLResponse
print("Status: \(httpResponse.statusCode)")
print(String(data: data, encoding: .utf8) ?? "")import Foundation
class ProxyDelegate: NSObject, URLSessionDelegate {
func urlSession(
_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
) {
let credential = URLCredential(
user: "USER", password: "PASS", persistence: .forSession
)
completionHandler(.useCredential, credential)
}
}
let config = URLSessionConfiguration.default
config.connectionProxyDictionary = [
kCFNetworkProxiesHTTPEnable: true,
kCFNetworkProxiesHTTPProxy: "gw.knoxproxy.com",
kCFNetworkProxiesHTTPPort: 7000,
kCFStreamPropertyHTTPSProxyHost: "gw.knoxproxy.com",
kCFStreamPropertyHTTPSProxyPort: 7000,
]
let session = URLSession(
configuration: config, delegate: ProxyDelegate(), delegateQueue: nil
)
let url = URL(string: "https://httpbin.org/ip")!
let task = session.dataTask(with: url) { data, _, error in
if let data = data {
print(String(data: data, encoding: .utf8) ?? "")
} else if let error = error {
print("Error: \(error.localizedDescription)")
}
}
task.resume()
RunLoop.main.run(until: Date(timeIntervalSinceNow: 10))Each URLSession task gets a fresh exit IP. For sticky sessions, set the username to USER-session-{id} in the delegate credential.
| Problem | Fix |
|---|---|
| NSURLErrorDomain Code=-1012 (authentication required) | Implement urlSession(_:didReceive:completionHandler:) in your URLSessionDelegate and return the proxy credential. |
| NSURLErrorDomain Code=-1004 (could not connect) | Verify gw.knoxproxy.com:7000 is reachable. Check that connectionProxyDictionary uses the correct key constants. |
USER-country-de-city-berlin-session-profile07Order matters -- geo flags before the session flag. The session name is free text; use the profile ID so the mapping is self-documenting. Password stays as issued; no flags belong there. HTTP on :7000, SOCKS5 on :7001, same credentials.
Yes, on macOS. Add kCFStreamPropertySOCKSProxyHost set to "gw.knoxproxy.com" and kCFStreamPropertySOCKSProxyPort set to 7001 inside the same connectionProxyDictionary used for the HTTP proxy keys shown above, rather than the kCFNetworkProxiesHTTPProxy and kCFNetworkProxiesHTTPPort pair used for the port 7000 HTTP gateway. Reuse the same URLSession built from that configuration for every subsequent request in your app.
Yes. Create the proxied URLSession once, using the same URLSessionConfiguration and ProxyDelegate shown above, then reuse it anywhere in a SwiftUI view or view model. Call try await session.data(from: url) inside any async function or .task modifier, and the KnoxProxy routing applies automatically with no extra setup for SwiftUI itself.
Each new dataTask through the proxied session gets a fresh KnoxProxy exit IP by default, since URLSession does not pin connections to one IP automatically. If a stubborn connection keeps reusing the same route, create a new URLSessionConfiguration and URLSession per request instead of reusing one long-lived session object across calls.
Yes. URLSession applies the connectionProxyDictionary settings the same way on both Wi-Fi and cellular data, so the proxy configuration does not change based on network type. IP allowlisting is not practical on mobile devices since cellular IPs change constantly, so use the URLSessionDelegate username and password authentication method described above instead.
Rotating residential proxies -- 5 minutes setup, instant activation, 14-day money-back guarantee.