axiom-networking-legacy
This skill should be used when working with NWConnection patterns for iOS 12-25, supporting apps that can't use async/await yet, or maintaining backward compatibility with completion handler networking.
Best use case
axiom-networking-legacy is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
This skill should be used when working with NWConnection patterns for iOS 12-25, supporting apps that can't use async/await yet, or maintaining backward compatibility with completion handler networking.
Teams using axiom-networking-legacy should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/axiom-networking-legacy/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How axiom-networking-legacy Compares
| Feature / Agent | axiom-networking-legacy | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
This skill should be used when working with NWConnection patterns for iOS 12-25, supporting apps that can't use async/await yet, or maintaining backward compatibility with completion handler networking.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Legacy iOS 12-25 NWConnection Patterns
These patterns use NWConnection with completion handlers for apps supporting iOS 12-25. If your app targets iOS 26+, use NetworkConnection with async/await instead (see axiom-network-framework-ref skill).
## Pattern 2a: NWConnection with TLS (iOS 12-25)
**Use when** Supporting iOS 12-25, need TLS encryption, can't use async/await yet
**Time cost** 10-15 minutes
### GOOD: NWConnection with Completion Handlers
```swift
import Network
// Create connection with TLS
let connection = NWConnection(
host: NWEndpoint.Host("mail.example.com"),
port: NWEndpoint.Port(integerLiteral: 993),
using: .tls // TCP inferred
)
// Handle connection state changes
connection.stateUpdateHandler = { [weak self] state in
switch state {
case .ready:
print("Connection established")
self?.sendInitialData()
case .waiting(let error):
print("Waiting for network: \(error)")
// Show "Waiting..." UI, don't fail immediately
case .failed(let error):
print("Connection failed: \(error)")
case .cancelled:
print("Connection cancelled")
default:
break
}
}
// Start connection
connection.start(queue: .main)
// Send data with pacing
func sendData() {
let data = Data("Hello, world!".utf8)
connection.send(content: data, completion: .contentProcessed { [weak self] error in
if let error = error {
print("Send error: \(error)")
return
}
// contentProcessed callback = network stack consumed data
// This is when you should send next chunk (pacing)
self?.sendNextChunk()
})
}
// Receive exact byte count
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.count) bytes")
// Process data...
self?.receiveData() // Continue receiving
}
}
}
```
### Key differences from NetworkConnection
- Must use `[weak self]` in all completion handlers to prevent retain cycles
- stateUpdateHandler receives state, not async sequence
- send/receive use completion callbacks, not async/await
### When to use
- Supporting iOS 12-15 (70% of devices as of 2024)
- Codebases not yet using async/await
- Libraries needing backward compatibility
### Migration to NetworkConnection (iOS 26+)
- stateUpdateHandler -> connection.states async sequence
- Completion handlers -> try await calls
- [weak self] -> No longer needed (async/await handles cancellation)
## Pattern 2b: NWConnection UDP Batch (iOS 12-25)
**Use when** Supporting iOS 12-25, sending multiple UDP datagrams efficiently, need ~30% CPU reduction
**Time cost** 10-15 minutes
**Background** Traditional UDP sockets send one datagram per syscall. If you're sending 100 small packets, that's 100 context switches. Batching reduces this to ~1 syscall.
### BAD: Individual UDP Sends (High CPU)
```swift
// WRONG — 100 context switches for 100 packets
for frame in videoFrames {
sendto(socket, frame.bytes, frame.count, 0, &addr, addrlen)
// Each send = context switch to kernel
}
```
### GOOD: Batched UDP Sends (30% Lower CPU)
```swift
import Network
// UDP connection
let connection = NWConnection(
host: NWEndpoint.Host("stream-server.example.com"),
port: NWEndpoint.Port(integerLiteral: 9000),
using: .udp
)
connection.stateUpdateHandler = { state in
if case .ready = state {
print("Ready to send UDP")
}
}
connection.start(queue: .main)
// Batch sending for efficiency
func sendVideoFrames(_ frames: [Data]) {
connection.batch {
for frame in frames {
connection.send(content: frame, completion: .contentProcessed { error in
if let error = error {
print("Send error: \(error)")
}
})
}
}
// All sends batched into ~1 syscall
// 30% lower CPU usage vs individual sends
}
// Receive UDP datagrams
func receiveFrames() {
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { [weak self] (data, context, isComplete, error) in
if let error = error {
print("Receive error: \(error)")
return
}
if let data = data {
// Process video frame
self?.displayFrame(data)
self?.receiveFrames() // Continue receiving
}
}
}
```
### Performance characteristics
- **Without batch** 100 datagrams = 100 syscalls = 100 context switches
- **With batch** 100 datagrams = ~1 syscall = 1 context switch
- **Result** ~30% lower CPU usage (measured with Instruments)
### When to use
- Real-time video/audio streaming
- Gaming with frequent updates (player position)
- High-frequency sensor data (IoT)
**WWDC 2018 demo** Live video streaming showed 30% lower CPU on receiver with user-space networking + batching
## Pattern 2c: NWListener (iOS 12-25)
**Use when** Need to accept incoming connections, building servers or peer-to-peer apps, supporting iOS 12-25
**Time cost** 20-25 minutes
### BAD: Manual Socket Listening
```swift
// WRONG — Manual socket management
let sock = socket(AF_INET, SOCK_STREAM, 0)
bind(sock, &addr, addrlen)
listen(sock, 5)
while true {
let client = accept(sock, nil, nil) // Blocks thread
// Handle client...
}
```
### GOOD: NWListener with Automatic Connection Handling
```swift
import Network
// Create listener with default parameters
let listener = try NWListener(using: .tcp, on: 1029)
// Advertise Bonjour service
listener.service = NWListener.Service(name: "MyApp", type: "_myservice._tcp")
// Handle service registration updates
listener.serviceRegistrationUpdateHandler = { update in
switch update {
case .add(let endpoint):
if case .service(let name, let type, let domain, _) = endpoint {
print("Advertising as: \(name).\(type)\(domain)")
}
default:
break
}
}
// Handle incoming connections
listener.newConnectionHandler = { [weak self] newConnection in
print("New connection from: \(newConnection.endpoint)")
// Configure connection
newConnection.stateUpdateHandler = { state in
switch state {
case .ready:
print("Client connected")
self?.handleClient(newConnection)
case .failed(let error):
print("Client connection failed: \(error)")
default:
break
}
}
// Start handling this connection
newConnection.start(queue: .main)
}
// Handle listener state
listener.stateUpdateHandler = { state in
switch state {
case .ready:
print("Listener ready on port \(listener.port ?? 0)")
case .failed(let error):
print("Listener failed: \(error)")
default:
break
}
}
// Start listening
listener.start(queue: .main)
// Handle client data
func handleClient(_ connection: NWConnection) {
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { [weak self] (data, context, isComplete, error) in
if let error = error {
print("Receive error: \(error)")
return
}
if let data = data {
print("Received \(data.count) bytes")
// Echo back
connection.send(content: data, completion: .contentProcessed { error in
if let error = error {
print("Send error: \(error)")
}
})
self?.handleClient(connection) // Continue receiving
}
}
}
```
### When to use
- Peer-to-peer apps (file sharing, messaging)
- Local network services
- Development/testing servers
### Bonjour advertising
- Automatic service discovery on local network
- No hardcoded IPs needed
- Works with NWBrowser for discovery
### Security considerations
- Use TLS parameters for encryption: `NWListener(using: .tls, on: port)`
- Validate client connections before processing data
- Set connection limits to prevent DoS
## Pattern 2d: Network Discovery (iOS 12-25)
**Use when** Discovering services on local network (Bonjour), building peer-to-peer apps, supporting iOS 12-25
**Time cost** 25-30 minutes
### BAD: Hardcoded IP Addresses
```swift
// WRONG — Brittle, requires manual configuration
let connection = NWConnection(host: "192.168.1.100", port: 9000, using: .tcp)
// What if IP changes? What if multiple devices?
```
### GOOD: NWBrowser for Service Discovery
```swift
import Network
// Browse for services on local network
let browser = NWBrowser(for: .bonjour(type: "_myservice._tcp", domain: nil), using: .tcp)
// Handle discovered services
browser.browseResultsChangedHandler = { results, changes in
for result in results {
switch result.endpoint {
case .service(let name, let type, let domain, _):
print("Found service: \(name).\(type)\(domain)")
// Connect to this service
self.connectToService(result.endpoint)
default:
break
}
}
}
// Handle browser state
browser.stateUpdateHandler = { state in
switch state {
case .ready:
print("Browser ready")
case .failed(let error):
print("Browser failed: \(error)")
default:
break
}
}
// Start browsing
browser.start(queue: .main)
// Connect to discovered service
func connectToService(_ endpoint: NWEndpoint) {
let connection = NWConnection(to: endpoint, using: .tcp)
connection.stateUpdateHandler = { state in
if case .ready = state {
print("Connected to service")
}
}
connection.start(queue: .main)
}
```
### When to use
- Peer-to-peer discovery (AirDrop-like features)
- Local network printers, media servers
- Development/testing (find test servers automatically)
### Performance characteristics
- mDNS-based (multicast DNS, no central server)
- Near-instant discovery on same subnet
- Automatic updates when services appear/disappear
### iOS 26+ alternative
- Use NetworkBrowser with Wi-Fi Aware for peer-to-peer without infrastructure
- See Pattern 1d in axiom-network-framework-ref skill
## Resources
**Skills**: axiom-networking, axiom-network-framework-ref, axiom-networking-migrationRelated Skills
legacy-circuit-mockups
Generate breadboard circuit mockups and visual diagrams using HTML5 Canvas drawing techniques. Use when asked to create circuit layouts, visualize electronic component placements, draw breadboard diagrams, mockup 6502 builds, generate retro computer schematics, or design vintage electronics projects. Supports 555 timers, W65C02S microprocessors, 28C256 EEPROMs, W65C22 VIA chips, 7400-series logic gates, LEDs, resistors, capacitors, switches, buttons, crystals, and wires.
legacy-modernizer
Refactor legacy codebases, migrate outdated frameworks, and implement gradual modernization. Handles technical debt, dependency updates, and backward compatibility. Use PROACTIVELY for legacy system updates, framework migrations, or technical debt reduction.
hybrid-cloud-networking
Configure secure, high-performance connectivity between on-premises infrastructure and cloud platforms using VPN and dedicated connections. Use when building hybrid cloud architectures, connecting data centers to cloud, or implementing secure cross-premises networking.
framework-migration-legacy-modernize
Orchestrate a comprehensive legacy system modernization using the strangler fig pattern, enabling gradual replacement of outdated components while maintaining continuous business operations through ex
axiom-audit
Audit Axiom logs to identify and prioritize errors and warnings, research probable causes, and flag log smells. Use when user asks to check Axiom logs, analyze production errors, investigate log issues, or audit logging patterns.
vibecoder-guide-legacy
Guides VibeCoder (non-technical users) through natural language development (legacy). Use when user mentions どうすればいい, 次は何, 使い方, 困った, help, what should I do. Do NOT load for: 技術者向け作業, 直接的な実装指示, レビュー.
p2p-networking
Peer-to-peer networking patterns using commonware for building decentralized Guts network
Axiom — Serverless Log Analytics
## Overview
Azure Networking Skill
This skill provides expert guidance for Azure Networking. Covers troubleshooting, best practices, decision making, architecture & design patterns, security, and integrations & coding patterns. It combines local quick-reference content with remote documentation fetching capabilities.
ios-networking
Standards for URLSession, Alamofire, and API communication. Use when implementing URLSession networking, Alamofire, or API clients in iOS. (triggers: **/*Service.swift, **/*API.swift, **/*Client.swift, URLSession, Alamofire, Moya, URLRequest, URLComponents, Codable)
flutter-retrofit-networking
HTTP networking standards using Dio and Retrofit with Auth interceptors. Use when integrating Dio, Retrofit, or API auth interceptors in Flutter. (triggers: **/data_sources/**, **/api/**, Retrofit, Dio, RestClient, GET, POST, Interceptor, refreshing)
android-networking
Standards for Retrofit, OkHttp, and API Communication. Use when integrating Retrofit, OkHttp, or API clients in Android apps. (triggers: **/*Api.kt, **/*Service.kt, **/*Client.kt, Retrofit, OkHttpClient, @GET, @POST)