A minimal network layer library for performing basic requests.
Platforms: iOS 13.0+ / macOS 10.15+
This library can be added as dependency in your project by using Swift Package Manager, which is integrated into the swift
compiler.
You'll need to add the following in your Package.swift
file:
Once you have your Swift package set up, adding Network as a dependency is as easy as adding it to the dependencies
value of your Package.swift
or the Package list in Xcode.
dependencies: [
.package(url: "https://github.com/martin-e91/swift-network.git", branch: "main")
]
Mainly you'll want to depend on the interface NetworkAPI
target
...
.target(name: "MyPackage", dependencies: [.product(name: "NetworkAPI", package: "swift-network")]),
...
while in the module where you'll need library's concrete types you'll want to depend on the concrete implementation target, Network
like so:
...
.target(name: "MyPackage", dependencies: [.product(name: "Network", package: "swift-network")]),
...
The package has been designed with modularisation in mind. For this reason its components have been split in between 3 exposed targets, that will result in a more flexible and decoupled integration in importing modules.
NetworkAPI
containing the module's interfaces. This module should be imported wherever you'll need to perform a request leveraging this library.Network
: containing concrete implementations of the components. Ideally this module should only be imported in your dependency injection layer, where you'll need to retrieve and inject concrete implementation components (likeNetworkClientFactoryImpl
).NetworkMocks
: this target exposes types for mockingNetworkAPI
protocols'.
Ideally you'd import the Network
module in your dependency injection layer, extracting a NetworkClient
instance from exposed factory NetworkClientFactoryImpl
, like so
struct AppDependencies {
let networkClient: NetworkClient
init() {
...
let factory = NetworkClientFactoryImpl()
self.networkClient = factory.networkClient(with: URLSession.shared)
...
}
}
After that, let's say you want to hit the PUNK API to retrieve a list of beers.
You'll want to declare a concrete Endpoint
struct PunkBeersEndpoint: Endpoint {
var scheme: String { "https" }
var host: String { "api.punkapi.com" }
var path: PathComponents { ["v2"] }
}
a concrete NetworkRequest
struct GetBeersRequest: NetworkRequest {
typealias Response = [Beer]
var method: HTTPMethod { .get }
var parameters: RequestParameter? { nil }
var endpoint: Endpoint { PunkBeersEndpoint() }
}
and finally you'll be able to hit the network with just 1 line of code
try await networkClient.perform(GetBeersRequest()) // will hit the network for the endpoint `https://api.punkapi.com/v2/beers`
Please feel free to open an issue for requesting a feature or reporting a bug.