Skip to content

ace4seven/Networker

Repository files navigation

Networker

iOS VersionSwift VersionSupported devices Dependency Manager

Networker is a complex API management solution built on Alamofire (https://github.com/Alamofire/Alamofire). The motivation was to create a scalable API manager focused on simplicity and the ability to cover all possible scenarios when building API infrastructure into a project.

Key Features

  1. Console logger for requests and responses
  2. Single file endpoints declaration
  3. Combine flow

Installation

Swift Package Manager

Copy link and add it into:

XCode -> Swift Packages -> Add Package Dependecy

If you have Package.swift, simple copy:

    dependencies: [
        .package(url: "https://github.com/ace4seven/Networker", from: "0.0.1")
    ],

Usage

By default console logger is set in the INFO. To change the log level, just write the following code.

NetworkerConfiguration.logLevel = .info

Log Levels:

  1. Info - Prints request url with response status and error when occurs.
  2. Error - Prints only when error occurs.
  3. Verbose - Prints everything including request body and response object

Endpoint Type

It is recommended to group all endpoints into a single enum file, which implements EndpointType protocol and define required attributes.

protocol EndpointType {
    var path: String { get }
    var method: HTTPMethod { get }
    var parameters: Encodable? { get }
    var headers: HTTPHeaders? { get }

    func baseUrl() throws -> URL
}

Endpoint implementation

enum Endpoint: EndpointType {

    case swapiPlanets

    var path: String {
        switch self {
        case .swapiPlanets: return "planets"
        }
    }

    var method: HTTPMethod {
        switch self {
        case .swapiPlanets: return .get
        }
    }

    func baseUrl() throws -> URL {
        switch self {
        case .swapiPlanets: return try "https://swapi.dev/api/".asURL()
        }
    }
}

Networker

The class is a wrapper for the Alamofire session object with a powerful call method, which transforms endpoint type into AnyPublisher containing Output as a Decodable object and Error object. Async await is also supported.

Combine publisher usage

private let networker = Networker<Endpoint>()

func getPlantets() -> AnyPublisher<PlanetsDto, Error> {
    networker
        .call(endpoint: .swapiPlanets)
}

Async await usage

private let networker = Networker<Endpoint>()

func getPlantets() async -> Result<PlanetsDto, Error> {
    await networker
        .call(endpoint: .swapiPlanets)
}

Info Error is Alamofire error - AFError


API Result

API Resul is a enum which control lifecycle of the request progress.

ApiResult.created - idle state

ApiResult.loading - loading state, called immediately after a request is called

ApiResult.loaded - loaded state containing response object (200..<400 response codes)

ApiResult.error - error state containing AFError object (400+ response codes)

Example

func getPlantets() -> AnyPublisher<ApiResult<PlanetsDto, Error>, Never> {
    networker
        .call(endpoint: .swapiPlanets)
        .mapToApiResult()
}

NetworkerError

All errors received from networker.call are NetworkerError enum type.

public enum NetworkerError: Error {

    case afError(AFError, Data?)
    case noInternet
}

There are two possible cases:

afError - Alamofire error with custom Payload data, if presented

noInternet - In case application is in offline mode

To cast Error in to the NetworkerError you can use provided extensions:

public extension Error {

    var payloadData: Data? {
        toNetworkerError()?.payloadData
    }

    func toNetworkerError() -> NetworkerError? {
        self as? NetworkerError
    }
}

About

Flexible API Manager

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages