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.
- 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, file uploading using multipart/form-data, and direct-to-disk file downloading. 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
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.1.1"))
]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"
)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
)
// Get raw response data
let (data, urlResponse) = try await EagleNet.post(
url: "https://api.example.com/users",
body: newUser
)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)
]
)let destinationDirectory = URL(fileURLWithPath: "/path/to/downloads")
let (localURL, response) = try await EagleNet.download(
url: "https://example.com/large-video.mp4",
destinationDirectory: destinationDirectory,
progress: { bytesDownloaded, totalBytes in
let progress = Float(bytesDownloaded) / Float(totalBytes)
print("Download progress: \(Int(progress * 100))%")
}
)destinationDirectory must resolve to a local file:// URL and point to a directory.
NetworkError.invalidFileURLis thrown when the value is not a local file URL.NetworkError.invalidDirectoryPathis thrown when the value points to a file instead of a directory.
Note: Background downloads and pause/resume tracking are currently not supported. Downloads will be cancelled if the application goes into the background or is terminated.
struct AuthInterceptor: RequestInterceptor {
let token: String
func modify(request: consuming URLRequest) async throws -> URLRequest {
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
return request
}
}
// Add interceptor to network service
EagleNet.addRequestInterceptor(
AuthInterceptor(token: "your-auth-token")
)struct LoggingInterceptor: ResponseInterceptor {
func modify(data: consuming Data, urlResponse: consuming 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())// 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)// Custom URLSession configuration
let customService = EagleNet.defaultService(
urlSession: URLSession(configuration: .ephemeral),
jsonEncoder: JSONEncoder(),
jsonDecoder: JSONDecoder(),
fileManager: .default
)
EagleNet.configure(networkService: customService)EagleNet is available under the MIT license. See the LICENSE file for more info.