Skip to content

A modern Swift networking library built with async/await concurrency patterns, featuring comprehensive error handling, automatic token management, and built-in testing support for iOS and macOS applications.

Notifications You must be signed in to change notification settings

grd888/ASNetworking

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ASNetworking

A modern Swift networking library built with async/await concurrency patterns, featuring comprehensive error handling, automatic token management, and built-in testing support for iOS and macOS applications.

Features

  • πŸš€ Modern Swift Concurrency - Built with async/await patterns
  • πŸ”§ Protocol-Based Architecture - Clean, testable request definitions
  • πŸ›‘οΈ Comprehensive Error Handling - Detailed error types with context
  • πŸ” Smart Token Management - Automatic token injection and refresh
  • πŸ“ Built-in Logging - Request/response logging for debugging
  • πŸ§ͺ Testing Support - Mock client with configurable responses
  • πŸ“± Multi-Platform - iOS 15+ and macOS 12+ support

Installation

Swift Package Manager

Add ASNetworking to your project using Xcode:

  1. File β†’ Add Package Dependencies
  2. Enter the repository URL
  3. Select the version you want to use

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/your-username/ASNetworking.git", from: "1.0.0")
]

Quick Start

1. Define Your API Requests

import ASNetworking

struct GetUserRequest: NetworkRequest {
    typealias Response = User
    
    let userId: Int
    
    var endpoint: String { "/users/\(userId)" }
    var method: HTTPMethod { .GET }
}

struct CreateUserRequest: NetworkRequest {
    typealias Response = User
    
    let user: CreateUserData
    
    var endpoint: String { "/users" }
    var method: HTTPMethod { .POST }
    var body: Encodable? { user }
}

2. Configure the Network Client

let configuration = NetworkClientConfiguration(
    baseURL: "https://api.example.com",
    jsonDecoder: JSONDecoder(),
    jsonEncoder: JSONEncoder()
)

let networkClient = NetworkClient(configuration: configuration)

3. Make Requests

// GET request
do {
    let user = try await networkClient.execute(GetUserRequest(userId: 123))
    print("User: \(user.name)")
} catch {
    print("Error: \(error)")
}

// POST request
do {
    let newUser = try await networkClient.execute(CreateUserRequest(user: userData))
    print("Created user: \(newUser.id)")
} catch {
    print("Error: \(error)")
}

Advanced Usage

Token Management

Implement automatic token injection and refresh:

class MyTokenProvider: TokenProvider {
    func getPrimaryToken() async -> String? {
        return "your-api-key"
    }
    
    func getSecondaryToken() async -> String? {
        return "your-bearer-token"
    }
    
    func requiresTokenRefresh() async -> Bool {
        // Check if token needs refresh
        return false
    }
    
    func getAdditionalHeaders() async -> [String: String]? {
        return ["X-App-Version": "1.0.0"]
    }
}

class MyTokenRefreshProvider: TokenRefreshProvider {
    var isTokenRefreshInProgress: Bool = false
    
    func refreshToken() async throws {
        // Implement token refresh logic
    }
    
    func waitForTokenRefresh() async {
        // Wait for ongoing refresh to complete
    }
}

let interceptor = DefaultRequestInterceptor(
    tokenProvider: MyTokenProvider(),
    tokenRefreshProvider: MyTokenRefreshProvider(),
    baseURL: "https://api.example.com"
)

let networkClient = NetworkClient(
    configuration: configuration,
    interceptor: interceptor
)

Custom Request Configuration

struct CustomRequest: NetworkRequest {
    typealias Response = MyResponse
    
    var endpoint: String { "/custom" }
    var method: HTTPMethod { .POST }
    var contentType: ContentType { .formURLEncoded }
    var timeoutInterval: TimeInterval { 60.0 }
    var headers: [String: String]? { ["Custom-Header": "value"] }
    var queryParameters: [String: String]? { ["param": "value"] }
}

Error Handling

do {
    let result = try await networkClient.execute(request)
} catch let error as NetworkError {
    switch error {
    case .unauthorized:
        // Handle authentication error
        break
    case .noConnection:
        // Handle network connectivity error
        break
    case .serverError(let statusCode, _):
        // Handle server errors
        print("Server error: \(statusCode)")
    case .decodingFailed(let decodingError, let data):
        // Handle JSON decoding errors
        print("Decoding failed: \(decodingError)")
    default:
        print("Other error: \(error.localizedDescription)")
    }
}

Testing with MockNetworkClient

import ASNetworking

let mockClient = MockNetworkClient()

// Configure mock responses
mockClient.setMockResponse(
    for: GetUserRequest.self,
    response: .success(User(id: 1, name: "Test User"))
)

mockClient.setMockResponse(
    for: CreateUserRequest.self,
    response: .failure(NetworkError.serverError(statusCode: 500, data: nil))
)

// Use in tests
let user = try await mockClient.execute(GetUserRequest(userId: 1))

Content Types

ASNetworking supports multiple content types:

  • JSON (application/json) - Default
  • Form URL Encoded (application/x-www-form-urlencoded)
  • Multipart Form Data (multipart/form-data)
struct FormRequest: NetworkRequest {
    typealias Response = EmptyResponse
    
    var endpoint: String { "/form" }
    var method: HTTPMethod { .POST }
    var contentType: ContentType { .formURLEncoded }
    var body: Encodable? { ["key": "value"] }
}

Logging

Enable request/response logging:

let logger = DefaultNetworkLogger()
let networkClient = NetworkClient(
    configuration: configuration,
    logger: logger
)

Requirements

  • iOS 15.0+ / macOS 12.0+
  • Swift 6.0+
  • Xcode 14.0+

πŸ™Œ Contributing

We welcome contributions to improve ASNetworking! πŸš€

πŸ“ Guidelines

  • Follow the existing code style and structure;
  • Write tests for any new functionality;
  • Open a pull request with a clear description of your changes;
  • Be respectful and constructive in discussions.

πŸ“„ License

This project is licensed under the MIT License.

About

A modern Swift networking library built with async/await concurrency patterns, featuring comprehensive error handling, automatic token management, and built-in testing support for iOS and macOS applications.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages