So the basic idea of Networkable is an ad-hoc network player built on top of URLSession
. It should be simple enough that common things are easy but comprehensive enough that complicated things are also easy.
Why not Alamofire/Moya?
Compared to them, Networkable is a tiny handy library, aimed at the most basic things of a network layer that should behave, triggers a request then handles the response. If you are the type of developer who wants to manipulate everything under your scope, then an understandable package may be the thing you favor.
/// An object provides methods for interacting with the crytocurrency market data in the remote database.
protocol RemoteCryptocurrencyMarketRepository {
/// Get all available exchanges.
/// - Parameter promise: A promise to be fulfilled with a result represents either a success or a failure.
/// - Returns: A URL session task that returns downloaded data directly to the app in memory.
@discardableResult
func exchangesTask(promise: @escaping (Result<[Exchange], Error>) -> Void) -> URLSessionDataTask?
/// Get all available exchanges.
/// - Returns: A publisher emits a list of exchanges
@available(macOS 10.15, macCatalyst 13.0, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func exchangesPublisher() -> AnyPublisher<[Exchange], Error>
/// Get all available exchanges.
/// - Returns: An asynchronously-delivered list of exchanges.
@available(macOS 12.0, macCatalyst 15.0, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func exchanges() async throws -> [Exchange]
}
/// An object provides methods for interacting with the crytocurrency market data in the remote database.
final class DefaultRemoteCryptocurrencyMarketRepository: RemoteCryptocurrencyMarketRepository {
// MARK: Dependencies
/// An ad-hoc network layer that is built on `URLSession` to perform an HTTP request.
let session: NetworkableSession
// MARK: Init
/// Initiate an object provides methods for interacting with the crytocurrency market data in the remote database.
/// - Parameter session: An ad-hoc network layer that is built on `URLSession` to perform an HTTP request.
init(session: NetworkableSession = NetworkSession.coincap) {
self.session = session
}
// MARK: RemoteCryptocurrencyMarketRepository
@discardableResult
func exchangesTask(promise: @escaping (Result<[Exchange], Error>) -> Void) -> URLSessionDataTask? {
session.dataTask(
for: API.exchanges,
resultQueue: nil,
decoder: JSONDecoder()
) { (result: Result<Datum<[Exchange]>, Error>) in
let exchanges = result.map { $0.data }
promise(exchanges)
}
}
@available(macOS 10.15, macCatalyst 13.0, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func exchangesPublisher() -> AnyPublisher<[Exchange], Error> {
session
.dataTaskPublisher(
for: API.exchanges,
resultQueue: nil,
decoder: JSONDecoder())
.map(\Datum<[Exchange]>.data)
.eraseToAnyPublisher()
}
@available(macOS 12.0, macCatalyst 15.0, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func exchanges() async throws -> [Exchange] {
let datum = try await session.data(for: API.exchanges, decoder: JSONDecoder()) as Datum<[Exchange]>
return datum.data
}
// MARK: Subtypes - API
/// An object abstracts an HTTP request.
private enum API: Request {
/// Get all available exchanges.
case exchanges
// MARK: Request
var headers: [String: String]? { nil }
var url: String { "/v2/exchanges" }
var method: Networkable.Method { .get }
func body() throws -> Data? { nil }
}
}
cd NetworkableExample
pod install
open NetworkableExample.xcworkspace/
Waits for the Cocoapods to generate the workspace then you're good to go.
Networkable
use cases should be found in UseCases
and Repositories
directory.
- Combine support
- async/await support
- Easy-peasy testing
- Lets you define a clear usage of different endpoints with associated enum values
- The middleware offers the capability of injecting logic:
- Authorization
- Localization
- Logging
- Error handling
- ...
- macOS 10.12+
- iOS 8.0+
- tvOS 10.0+
- watchOS 3.0+
Embedded in a package
dependencies: [
.package(url: "https://github.com/duytph/Networkable"),
]
Embedded in Xcode project
- Open menu File > Swift Packages > Add Package Dependency...
- Enter https://github.com/duytph/Networkable
pod 'Networkable'
Not implemented
Duy Tran ([email protected])
Networkable is available under the MIT license. See the LICENSE file for more info.