# 🚀 EagleNet – A Lightweight Networking library for Swift

Hi everyone :waving_hand:

I’d like to share EagleNet, a lightweight networking library for Swift that builds directly on top of Foundation’s URLSession, providing a structured and ergonomic way to define requests and handle responses using modern Swift concurrency.

:link: GitHub: GitHub - AnbalaganD/EagleNet: Simple lightweight networking layer written on top of URLSession. This will provide a clean, separate layer for networking.


:sparkles: Key Features

  • Thin, transparent layer over URLSession (no heavy dependencies)
  • Supports GET, POST, PUT, DELETE, and custom HTTP methods
  • Multipart file uploads with progress tracking
  • Request & response interceptors (authentication, logging, etc.)
  • Flexible configuration with custom URLSession instances
  • Designed around Swift’s async/await, with a focus on safety and clarity

Basic Example

import EagleNet

struct User: Decodable {
    let id: Int
    let name: String
    let email: String
}

// Basic GET request
let user: User = try await EagleNet.get(
    url: "https://api.example.com/users/1"
)

// Get raw response data
let (data, response) = try await EagleNet.get(
    url: "https://api.example.com/users/1"
)

File Upload

let imageData = // ... your image data ...
let response: UploadResponse = try await EagleNet.upload(
    url: "https://api.example.com/upload",
    parameters: [
        .file(
            key: "avatar",
            fileName: "profile.jpg",
            data: imageData,
            mimeType: .jpegImage
        ),
        .text(key: "username", value: "Anbu")
    ],
    progress: { bytesTransferred, totalBytes in
        let progress = Float(bytesTransferred) / Float(totalBytes)
        print("Upload progress: \(Int(progress * 100))%")
    }
)

// Get raw response data
let (data, urlResponse) = try await EagleNet.upload(
    url: "https://api.example.com/upload",
    parameters: [
        .file(key: "avatar", fileName: "profile.jpg", data: imageData, mimeType: .jpegImage)
    ]
)

Request Interceptors

struct AuthInterceptor: RequestInterceptor {
    let token: String
    
    func modify(request: URLRequest) async throws -> URLRequest {
        var modifiedRequest = request
        modifiedRequest.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        return modifiedRequest
    }
}

// Add interceptor to network service
EagleNet.addRequestInterceptor(
    AuthInterceptor(token: "your-auth-token")
)

Response Interceptors

struct LoggingInterceptor: ResponseInterceptor {
    func modify(data: Data, urlResponse: URLResponse) async throws -> (Data, URLResponse) {
        if let httpResponse = urlResponse as? HTTPURLResponse {
            print("Response Status Code: \(httpResponse.statusCode)")
            print("Response Headers: \(httpResponse.allHeaderFields)")
            
            if let responseString = String(data: data, encoding: .utf8) {
                print("Response Body: \(responseString)")
            }
        }
        return (data, urlResponse)
    }
}

// Add response interceptor to network service
EagleNet.addResponseInterceptor(LoggingInterceptor())

:bullseye: Design Goals

EagleNet does not replace Foundation networking APIs.
Instead, it aims to:

  • Organize networking code around clear request/response types
  • Reduce repetitive setup while preserving full control
  • Remain easy to test and extend
  • Stay close to native Swift and Foundation concepts

It’s intended for iOS, macOS, and tvOS projects where a small, predictable abstraction over URLSession is helpful.

:raising_hands: Feedback Welcome

I’d really appreciate feedback, design suggestions, or contributions.
And if you find it useful, a :star: on GitHub would mean a lot.

Thanks for reading! :blush:

3 Likes