EagleNet

2.0.0

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

What's New

2.0.0

2025-10-08T10:47:26Z

Release Notes - EagleNet 2.0.0

🚨 Breaking Changes

Removed BodyConvertible Protocol

The BodyConvertible protocol has been removed to simplify the API. Request bodies now use the Body typealias (any Encodable), which accepts any Encodable type or Data directly.

Migration Required:

Before (v1.x):

// Custom BodyConvertible conformance
extension MyCustomType: BodyConvertible {
    func asBody(encoder: JSONEncoder) throws -> Data {
        // custom encoding logic
    }
}

// Using asBodyConvertible()
let body = myEncodable.asBodyConvertible()

After (v2.0):

// Just conform to Encodable
struct MyCustomType: Encodable {
    // standard Encodable conformance
}

// Use directly - no wrapper needed
let body = myEncodable

Removed APIs

  • BodyConvertible protocol
  • AnyBodyConvertible internal wrapper
  • Encodable.asBodyConvertible() extension method
  • DataRequest.setBody(_ body: some BodyConvertible) overload

What Still Works

✅ All Encodable types work directly as body
Data can be passed as body (sent as-is without encoding)
✅ All convenience methods (GET, POST, PUT, DELETE) unchanged
✅ Custom NetworkRequestable implementations work with Body type

🎯 Improvements

  • Simpler API - No need to understand BodyConvertible protocol
  • Better performance - Removed double type-erasure overhead
  • Clearer intent - Body typealias makes it obvious what's accepted

📝 Migration Steps

  1. Remove any BodyConvertible conformances - use Encodable instead
  2. Remove calls to .asBodyConvertible() - pass values directly
  3. If using Data as body, it continues to work without changes

Full Changelog: 1.1.0...2.0.0

This library aims to provide a simple and elegant approach to writing network requests. It's designed to be lightweight, adding a thin layer on top of URLSession without excessive engineering overhead.

Our primary objectives are:

  • Lightweight networking library: Keep the library small and efficient.
  • Easy to maintain: Prioritize clear code and modular design for maintainability.
  • Beginner friendly: Make the library accessible to developers of all levels.
  • Well documented: Provide comprehensive documentation to guide usage.
  • Customizable and testable: Allow for flexibility and ensure code quality through testing.

Currently, this library supports basic HTTP data requests (GET, POST, PUT, DELETE), custom HTTP methods, and includes a small file upload feature using multipart/form-data. These capabilities address the majority of network communication needs in most applications.

For detailed information on feature status, please refer to the Roadmap file.

See the complete documentation here: Documentation

Swift Package Manager (SPM)

EagleNet is available through SPM. Use the URL below to add it as a dependency.

dependencies: [
    .package(url: "https://github.com/AnbalaganD/EagleNet", .upToNextMajor(from: "2.0.0"))
]

Making a GET Request

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"
)

Making a POST Request

struct CreateUser: Encodable {
    let name: String
    let email: String
}

struct UserResponse: Decodable {
    let id: Int
    let name: String
}

let newUser = CreateUser(name: "Anbalagan D", email: "anbu94p@gmail.com")
let response: UserResponse = try await EagleNet.post(
    url: "https://api.example.com/users",
    body: newUser
)

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))%")
    }
)

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())

Custom HTTP Methods

// Using custom HTTP methods like PATCH
struct UpdateStatus: Encodable {
    let status: String
}

let patchRequest = DataRequest(
    url: "https://api.example.com/users/1",
    httpMethod: .custom("PATCH"),
    body: UpdateStatus(status: "active")
)

let response: User = try await EagleNet.execute(patchRequest)

Configuration

// Custom URLSession configuration
let customService = EagleNet.defaultService(
    urlSession: URLSession(configuration: .ephemeral),
    jsonEncoder: JSONEncoder(),
    jsonDecoder: JSONDecoder()
)

EagleNet.configure(networkService: customService)

Author

Anbalagan D

License

EagleNet is available under the MIT license. See the LICENSE file for more info.

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Oct 26 2025 17:54:14 GMT-0900 (Hawaii-Aleutian Daylight Time)