Swiftpack.co - fsalom/TripleA as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by fsalom.
fsalom/TripleA 1.0.21
swift package to handle api calls easy way
⭐️ 0
🕓 5 days ago
iOS
.package(url: "https://github.com/fsalom/TripleA.git", from: "1.0.21")

Swift Swift Package Manager

TripleA: Async Await API

✍️ About

TripleA is an acronym for Async Await API in swift. It is a package created to simplify task of using REST API. It is main purpose is to be used with Rudo APIs. At the core of the system is URLSession and the URLSessionTask subclasses. TripleAAA wraps these APIs and provide a way to simplify and reduce code to make it easier to use calls to APIs

📦 Installation

Swift Package Manager

To install TripleA using Swift Package Manager you can follow the tutorial published by Apple using the URL for the TipleAAA repo with the current version:

In Xcode, select “File” → “Swift Packages” → “Add Package Dependency”

Enter https://github.com/fsalom/TripleA

🦾 Core elements

There are 4 main pieces in this system. Each one of them is responsable of their own area.

  • Network: responsable of making calls and parse objects.
  • Endpoint: Its the way endpoint request are built for TripleA.
  • AuthManager: responsable of managing tokens and refresh them.
  • TokenStore: responsable of storing token information (by default UserDefaults)

Network

It is the core of this package. It provides different ways of calling an API.

public init(baseURL: String,
            authManager: AuthManager? = nil,
            headers: [String: String] = [:],
            format: LogFormat = .full)
            
Network(baseURL: "https://api.coincap.io/v2/")

Required properties:

  • baseURL: url to endpoint

Optional properties:

  • authManager: manager to handle authentication
  • headers: header for all the endpoints
  • format: log formatter for console (.full, .short, .custom(), .none)

Endpoint

Each endpoint has its own Endpoint object. This object has different properties to create the request

public init(path: String,
            contentType: ContentType? = nil,
            httpMethod: HTTPMethod,
            body: Data? = nil,
            parameters: [String: Any] = [:],
            headers: [String: String] = [:],
            query: [String: Any] = [:])
            
Endpoint(path: "https://api.coincap.io/v2/assets", httpMethod: .get)

Required properties:

  • path: url to endpoint
  • httpMethod: .get, .post, .put, .delete ...

Optional properties:

  • parameters:
  • headers:
  • query:
  • contentType:
  • body:

🚀 Usage non authorized API

As an example we will use https://coincap.io and their crypto list. This API is free to use and do not have any kind of authentication system

Defining dependency injection

Container.swift

Network(baseURL: "https://api.coincap.io/v2/")

DTO declaration

CryptoDTO

struct ListDTO: Codable {
    let data : [CryptoDTO]
}

struct CryptoDTO: Codable {
    let name : String!
    let priceUsd : String!
    let changePercent24Hr : String!
}

Endpoint

CryptoAPI

enum CryptoAPI {
    case assets
    var endpoint: Endpoint {
        get {
            switch self {
            case .assets:
                return Endpoint(path: "assets", httpMethod: .get)
            }
        }
    }
}

Making request

ViewModel

Task{
    do {
        _ = try await network.load(endpoint: CryptoAPI.assets.endpoint, of: ListDTO.self)
    } catch {

    }
}

🔒 Usage authorized API

An example for OAUTH2 grant_type = password

Defining dependency injection

Container.swift

let storage = AuthTokenStoreDefault()
let remoteDataSource = OAuthGrantTypePasswordManager(storage: storage, startController: getLoginController(), refreshTokenEndpoint: OAuthAPI.refresh(parametersRefresh).endpoint, tokensEndPoint: OAuthAPI.login(parametersLogin).endpoint)
let authManager = AuthManager(storage: storage,
                              remoteDataSource: remoteDataSource,
                              parameters: [:])
let network = Network(baseURL: "https://dashboard.rudo.es/", authManager: authManager)

DTO declaration

UserDTO

struct UserDTO: Codable {
    let firstName,
        email: String

    private enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
        case email = "email"
    }
}

Endpoint

OauthAPI

enum OAuthAPI {
    case login([String: Any])
    case refresh([String: Any])
    case me
    var endpoint: Endpoint {
        get {
            switch self {
            case .login(let parameters):
                return Endpoint(baseURL: "https://dashboard.rudo.es/", path: "auth/token/", httpMethod: .post, parameters: parameters)
            case .refresh(let parameters):
                return Endpoint(baseURL: "https://dashboard.rudo.es/", path: "auth/token/", httpMethod: .post, parameters: parameters)
            case .me:
                return Endpoint(path: "users/me/", httpMethod: .get)
            }
        }
    }
}

Usage

Login

let parameters = ["grant_type": "password",
                  "username": "XXXX",
                  "password": "XXXX",
                  "client_id": "XXXX",
                  "client_secret": "XXXX"]
try await Container.network.getNewToken(with: parameters)

Calls

try await Container.network.loadAuthorized(endpoint: OAuthAPI.me.endpoint, of: UserDTO.self)

📚 Examples

This repo includes an iOS example, which is attached to Example.xcodeproj

👨‍💻 Author

Fernando Salom

GitHub

link
Stars: 0
Last commit: 3 days ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

v1.0.20
1 week ago

Add option to provide a start controller or not in cases like when using swiftui could be useful

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics