axiom-networking-migration

Network Framework Migration Guides

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "axiom-networking-migration" with this command: npx skills add charleswiltgen/axiom/charleswiltgen-axiom-axiom-networking-migration

Network Framework Migration Guides

Do I Need to Migrate?

What networking API are you using?

├─ URLSession for HTTP/HTTPS REST APIs? │ └─ Stay with URLSession — it's the RIGHT tool for HTTP │ URLSession handles caching, cookies, auth challenges, │ HTTP/2/3, and is heavily optimized for web APIs. │ Network.framework is for custom protocols, NOT HTTP. │ ├─ BSD Sockets (socket, connect, send, recv)? │ └─ Migrate to NWConnection (iOS 12+) │ → See Migration 1 below │ ├─ NWConnection / NWListener? │ ├─ Need async/await? → Migrate to NetworkConnection (iOS 26+) │ │ → See Migration 2 below │ └─ Callback-based code working fine? → Stay (not deprecated) │ ├─ URLSession StreamTask for TCP/TLS? │ └─ Need UDP or custom protocols? → NetworkConnection │ Need just TCP/TLS for HTTP? → Stay with URLSession │ → See Migration 3 below │ ├─ SCNetworkReachability? │ └─ DEPRECATED — Replace with NWPathMonitor (iOS 12+) │ let monitor = NWPathMonitor() │ monitor.pathUpdateHandler = { path in │ print(path.status == .satisfied ? "Online" : "Offline") │ } │ └─ CFSocket / NSStream? └─ DEPRECATED — Replace with NWConnection (iOS 12+) → See Migration 1 below

Migration 1: From BSD Sockets to NWConnection

Migration mapping

BSD Sockets NWConnection Notes

socket() + connect()

NWConnection(host:port:using:) + start()

Non-blocking by default

send() / sendto()

connection.send(content:completion:)

Async, returns immediately

recv() / recvfrom()

connection.receive(minimumIncompleteLength:maximumLength:completion:)

Async, returns immediately

bind() + listen()

NWListener(using:on:)

Automatic port binding

accept()

listener.newConnectionHandler

Callback for each connection

getaddrinfo()

Let NWConnection handle DNS Smart resolution with racing

SCNetworkReachability

connection.stateUpdateHandler waiting state No race conditions

setsockopt()

NWParameters configuration Type-safe options

Example migration

Before (BSD Sockets)

// BEFORE — Blocking, manual DNS, error-prone var hints = addrinfo() hints.ai_family = AF_INET hints.ai_socktype = SOCK_STREAM

var results: UnsafeMutablePointer<addrinfo>? getaddrinfo("example.com", "443", &hints, &results)

let sock = socket(results.pointee.ai_family, results.pointee.ai_socktype, 0) connect(sock, results.pointee.ai_addr, results.pointee.ai_addrlen) // BLOCKS

let data = "Hello".data(using: .utf8)! data.withUnsafeBytes { ptr in send(sock, ptr.baseAddress, data.count, 0) }

After (NWConnection)

// AFTER — Non-blocking, automatic DNS, type-safe let connection = NWConnection( host: NWEndpoint.Host("example.com"), port: NWEndpoint.Port(integerLiteral: 443), using: .tls )

connection.stateUpdateHandler = { state in if case .ready = state { let data = Data("Hello".utf8) connection.send(content: data, completion: .contentProcessed { error in if let error = error { print("Send failed: (error)") } }) } }

connection.start(queue: .main)

Benefits

  • 20 lines → 10 lines

  • No manual DNS, no blocking, no unsafe pointers

  • Automatic Happy Eyeballs, proxy support, WiFi Assist

Migration 2: From NWConnection to NetworkConnection (iOS 26+)

Why migrate

  • Async/await eliminates callback hell

  • TLV framing and Coder protocol built-in

  • No [weak self] needed (async/await handles cancellation)

  • State monitoring via async sequences

Migration mapping

NWConnection (iOS 12-25) NetworkConnection (iOS 26+) Notes

connection.stateUpdateHandler = { state in }

for await state in connection.states { }

Async sequence

connection.send(content:completion:)

try await connection.send(content)

Suspending function

connection.receive(minimumIncompleteLength:maximumLength:completion:)

try await connection.receive(exactly:)

Suspending function

Manual JSON encode/decode Coder(MyType.self, using: .json)

Built-in Codable support

Custom framer TLV { TLS() }

Built-in Type-Length-Value

[weak self] everywhere No [weak self] needed Task cancellation automatic

Example migration

Before (NWConnection)

// BEFORE — Completion handlers, manual memory management let connection = NWConnection(host: "example.com", port: 443, using: .tls)

connection.stateUpdateHandler = { [weak self] state in switch state { case .ready: self?.sendData() case .waiting(let error): print("Waiting: (error)") case .failed(let error): print("Failed: (error)") default: break } }

connection.start(queue: .main)

func sendData() { let data = Data("Hello".utf8) connection.send(content: data, completion: .contentProcessed { [weak self] error in if let error = error { print("Send error: (error)") return } self?.receiveData() }) }

func receiveData() { connection.receive(minimumIncompleteLength: 10, maximumLength: 10) { [weak self] (data, context, isComplete, error) in if let error = error { print("Receive error: (error)") return } if let data = data { print("Received: (data)") } } }

After (NetworkConnection)

// AFTER — Async/await, automatic memory management let connection = NetworkConnection( to: .hostPort(host: "example.com", port: 443) ) { TLS() }

// Monitor states in background task Task { for await state in connection.states { switch state { case .preparing: print("Connecting...") case .ready: print("Ready") case .waiting(let error): print("Waiting: (error)") case .failed(let error): print("Failed: (error)") default: break } } }

// Send and receive with async/await func sendAndReceive() async throws { let data = Data("Hello".utf8) try await connection.send(data)

let received = try await connection.receive(exactly: 10).content
print("Received: \(received)")

}

Benefits

  • 30 lines → 15 lines

  • No callback nesting, no [weak self]

  • Errors propagate naturally with throws

  • Automatic cancellation on Task exit

Migration 3: From URLSession StreamTask to NetworkConnection

When to migrate

  • Need UDP (StreamTask only supports TCP)

  • Need custom protocols beyond TCP/TLS

  • Need low-level control (packet pacing, ECN, service class)

When to STAY with URLSession

  • Doing HTTP/HTTPS (URLSession optimized for this)

  • Need WebSocket support

  • Need built-in caching, cookie handling

Example migration

Before (URLSession StreamTask)

// BEFORE — URLSession for TCP/TLS stream let task = URLSession.shared.streamTask(withHostName: "example.com", port: 443)

task.resume()

task.write(Data("Hello".utf8), timeout: 10) { error in if let error = error { print("Write error: (error)") } }

task.readData(ofMinLength: 10, maxLength: 10, timeout: 10) { data, atEOF, error in if let error = error { print("Read error: (error)") return } if let data = data { print("Received: (data)") } }

After (NetworkConnection)

// AFTER — NetworkConnection for TCP/TLS let connection = NetworkConnection( to: .hostPort(host: "example.com", port: 443) ) { TLS() }

func sendAndReceive() async throws { try await connection.send(Data("Hello".utf8)) let data = try await connection.receive(exactly: 10).content print("Received: (data)") }

Resources

Skills: axiom-ios-networking, axiom-networking-legacy

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

axiom-vision

No summary provided by upstream source.

Repository SourceNeeds Review
General

axiom-swiftdata

No summary provided by upstream source.

Repository SourceNeeds Review
General

axiom-swiftui-26-ref

No summary provided by upstream source.

Repository SourceNeeds Review
General

axiom-swiftui-architecture

No summary provided by upstream source.

Repository SourceNeeds Review