home / skills / rshankras / claude-code-apple-skills / networking-layer

networking-layer skill

/skills/generators/networking-layer

This skill generates a protocol-based Swift networking layer using async/await, with configurable authentication, error handling, and testability.

npx playbooks add skill rshankras/claude-code-apple-skills --skill networking-layer

Review the files below or copy the command above to add this skill to your agents.

Files (7)
SKILL.md
4.3 KB
---
name: networking-layer
description: Generates a protocol-based networking layer with async/await, error handling, and swappable implementations. Use when user wants to add API client, networking, or HTTP layer.
allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion]
---

# Networking Layer Generator

Generate a modern, protocol-based networking layer using Swift's async/await concurrency, with proper error handling and easy testability.

## When This Skill Activates

Use this skill when the user:
- Asks to "add networking" or "create API client"
- Mentions "HTTP layer" or "REST API"
- Wants to "fetch data from API"
- Asks about "URLSession wrapper" or "network requests"

## Pre-Generation Checks

### 1. Project Context Detection
- [ ] Check Swift version (async/await requires Swift 5.5+)
- [ ] Check deployment target (async/await requires iOS 15+ / macOS 12+)
- [ ] Search for existing networking implementations
- [ ] Identify source file locations

### 2. Conflict Detection
Search for existing networking:
```
Glob: **/*API*.swift, **/*Network*.swift, **/*Client*.swift
Grep: "URLSession" or "HTTPURLResponse"
```

If found, ask user:
- Replace existing implementation?
- Extend with new endpoints?

## Configuration Questions

Ask user via AskUserQuestion:

1. **Authentication type?**
   - Bearer token
   - API key (header or query param)
   - None
   - Custom

2. **Base URL configuration?**
   - Single environment
   - Multiple environments (dev/staging/prod)

3. **Additional features?**
   - Retry logic with exponential backoff
   - Request/response logging
   - Caching

## Generation Process

### Step 1: Create Core Files

Generate these files:
1. `APIClient.swift` - Protocol and implementation
2. `APIEndpoint.swift` - Endpoint definition protocol
3. `NetworkError.swift` - Typed errors
4. `APIConfiguration.swift` - Base URL and auth config

### Step 2: Optional Files

Based on configuration:
- `RetryPolicy.swift` - If retry logic selected
- `NetworkLogger.swift` - If logging selected

### Step 3: Determine File Location

Check project structure:
- If `Sources/` exists → `Sources/Networking/`
- If `App/` exists → `App/Networking/`
- Otherwise → `Networking/`

## Swift 6.2 Concurrency Notes

Reference: Apple's Swift Concurrency Updates

### @concurrent for Background Work
Use `@concurrent` to offload heavy processing:
```swift
@concurrent
static func parseResponse<T: Decodable>(_ data: Data) async throws -> T {
    try JSONDecoder().decode(T.self, from: data)
}
```

### MainActor for UI Updates
Keep UI-related code on MainActor:
```swift
@MainActor
class NetworkViewModel: ObservableObject {
    @Published var items: [Item] = []

    func fetch() async {
        items = try await apiClient.fetch(ItemsEndpoint())
    }
}
```

## Output Format

After generation, provide:

### Files Created
```
Sources/Networking/
├── APIClient.swift           # Protocol + URLSession implementation
├── APIEndpoint.swift         # Endpoint protocol
├── NetworkError.swift        # Error types
├── APIConfiguration.swift    # Config (base URL, auth)
└── Endpoints/                # Example endpoints
    └── ExampleEndpoint.swift
```

### Integration Steps

**Define an Endpoint:**
```swift
struct UsersEndpoint: APIEndpoint {
    typealias Response = [User]

    var path: String { "/users" }
    var method: HTTPMethod { .get }
}
```

**Make a Request:**
```swift
let client = URLSessionAPIClient(configuration: .production)
let users = try await client.request(UsersEndpoint())
```

**With SwiftUI:**
```swift
struct UsersView: View {
    @State private var users: [User] = []
    @Environment(\.apiClient) private var apiClient

    var body: some View {
        List(users) { user in
            Text(user.name)
        }
        .task {
            users = try await apiClient.request(UsersEndpoint())
        }
    }
}
```

### Testing

Use `MockAPIClient` for tests:
```swift
let mockClient = MockAPIClient()
mockClient.mockResponse(for: UsersEndpoint.self, response: [User.mock])

let viewModel = UsersViewModel(apiClient: mockClient)
await viewModel.fetch()

XCTAssertEqual(viewModel.users.count, 1)
```

## References

- **networking-patterns.md** - Architecture patterns and best practices
- **templates/** - All template files
- Apple Docs: Swift Concurrency Updates (Swift 6.2)

Overview

This skill generates a modern, protocol-based networking layer in Swift that leverages async/await, structured error handling, and swappable implementations for easy testing. It creates a small, opinionated file set (APIClient, APIEndpoint, NetworkError, APIConfiguration) and optional utilities like retry policies and logging. The output is ready to drop into typical project layouts and includes example endpoints and testing helpers.

How this skill works

The generator inspects project context (Swift and deployment targets) and scans for existing networking files to avoid conflicts. It produces a protocol-driven APIClient and endpoint types that use URLSession under the hood with async/await, plus typed NetworkError and a configuration object for base URLs and auth. Optional features such as retry logic and request/response logging are added when selected, and a MockAPIClient is provided for unit tests.

When to use it

  • Adding an API client or HTTP layer to a Swift app using async/await
  • Replacing or standardizing multiple ad-hoc network calls with a single protocol-based client
  • Adding testable networking with swappable mock implementations
  • Needing configurable base URL and authentication (bearer, API key, or custom)
  • Adding retry, logging, or caching as cross-cutting network features

Best practices

  • Confirm project uses Swift 5.5+ and deployment targets that support async/await (iOS 15+/macOS 12+)
  • Prefer APIEndpoint types per resource to keep requests typed and decodable
  • Inject APIClient via dependency injection or Environment for easy mocking
  • Enable logging and retries only in debugging or configurable environments
  • Keep UI updates on MainActor; perform parsing and heavy work off the main thread

Example use cases

  • Generate core networking files and add a UsersEndpoint to fetch user lists via async/await
  • Create a MockAPIClient for unit tests of view models without hitting real network
  • Add retry policy with exponential backoff for flaky endpoints and optional logging for debugging
  • Support multiple environments (dev/staging/prod) via APIConfiguration with environment targets
  • Swap URLSession implementation for a custom transport (e.g., Unix domain socket or specialized client)

FAQ

What Swift and platform versions are required?

Async/await requires Swift 5.5+ and deployment targets that support concurrency (iOS 15+, macOS 12+).

Can I replace an existing networking implementation?

Yes. The generator scans for existing API/Network/Client files and will prompt whether to replace or extend endpoints.