SwiftAPIGate is a lightweight network layer for Swift applications, inspired by the Moya framework. It provides a simplified and efficient approach for handling API calls in iOS and macOS applications.
Install SwiftAPIGate using the Swift Package Manager. Add it as a dependency in your Package.swift
file:
dependencies: [
.package(url: "https://github.com/ugoArangino/SwiftAPIGate.git", branch("main")
]
To use SwiftAPIGate, import the package and create a view model that handles your network requests. Here is a basic example:
import SwiftAPIGate
@Observable
final class GitHubOrganizationsViewModel {
private var middleware: ExampleTargetMiddleware
private let provider: APIGate<ExampleTarget>
private(set) var organizations: [Organization]?
private(set) var error: Error?
init() {
// Injecting a middleware into the provider to modify the requests
let middleware = ExampleTargetMiddleware()
self.middleware = middleware
provider = .init(middleware: middleware)
}
func load() async {
do {
// Using .value to access the decoded data
organizations = try await provider.request(.gitHubOrganizations).value
} catch {
self.error = error
}
}
}
The Target
is a key component in SwiftAPIGate. It defines the endpoints for your network requests. Here's an example of how to create a target:
struct ExampleBody: Codable, Equatable {
let date: Date
let id: UUID
init(date: Date = .now, id: UUID = .init()) {
self.date = date
self.id = id
}
}
enum ExampleTarget {
case gitHubOrganizations
// Use case associated values to pass data to the request
case httpbinPOST(ExampleBody)
private static let encoder: JSONEncoder = {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
return encoder
}()
}
extension ExampleTarget: TargetType {
var baseURL: URL {
switch self {
case .gitHubOrganizations:
URL(string: "https://api.github.com")!
case .httpbinPOST:
URL(string: "https://httpbin.org")!
}
}
var path: String {
switch self {
case .gitHubOrganizations:
"/organizations"
case .httpbinPOST:
"/post"
}
}
var method: HTTPMethod {
switch self {
case .gitHubOrganizations:
.get
case .httpbinPOST:
.post
}
}
var validationType: ValidationType {
.successAndRedirectCodes
}
var headers: [String: String]? {
nil
}
var body: Data? {
switch self {
case .gitHubOrganizations:
nil
case let .httpbinPOST(body):
try? Self.encoder.encode(body)
}
}
}
Middleware in SwiftAPIGate allows you to intercept requests and responses, adding additional functionality or modifying the request/response as needed. Here's a simple example of middleware usage:
class ExampleTargetMiddleware: MiddlewareType {
// Use this method to modify the target before it is used to create a request
// E.g. Changing the baseURL for a development environment
func target(_ target: some SwiftAPIGate.TargetType) -> SwiftAPIGate.AbstractTarget? {
.init(from: target, withPath: "users/\(mode.rawValue)/orgs")
}
// Use this method to modify the raw request before it is sent
func request(_: URLRequest, _: some SwiftAPIGate.TargetType) -> URLRequest? {
nil
}
}