Skip to content

Framework for abstracting RESTful api requests

License

Notifications You must be signed in to change notification settings

rauhul/api-manager

Repository files navigation

APIManager

Swift Version Build Status Documentation Converage Release Version GitHub License

APIManager is a framework for abstracting RESTful API requests.

Requirements

  • Swift 5.0+

Notes

  • APIManager 0.3.0 is the last version that supports cocoapods
  • APIManager 0.3.0 is the last release with Swift 4.2 support
  • APIManager 0.0.5 is the last release with Swift 3 support

Installation

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.

Once you have your Swift package set up, adding APIManager as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .Package(url: "https://github.com/rauhul/api-manager.git", from: "0.4.0")
]

Usage

APIManager relies on users to create APIServices and APIReturnable types relevent to the RESTful APIs they are working with. APIServices contain descriptions of various endpoints that return their responses as native swift objects.

Making an APIReturnable Type

An APIReturnable Type only needs to conform to one method init(from: Data) throws. APIManager extends Decodable types to also be APIReturnable. An example implementation can be found below:

extension APIReturnable where Self: Decodable {
    init(from data: Data) throws {
        self = try JSONDecoder().decode(Self.self, from: data)
    }
}

Making an APIService

An APIService is made up of 3 components.

  1. A baseURL. Endpoints in this service will be postpended to this URL segment. As a result a baseURL will generally look like the root URL of the API the service communicates with.
open class var baseURL: String {
    return "https://api.example.com"
}
  1. HTTPHeaders to be sent alongside the APIRequests made by the endpoints in your APIService.
open class var headers: HTTPHeaders? {
    return [
        "Content-Type": "application/json"
    ]
}
  1. A set of RESTful api endpoints that you would like to use. These should be simple wrappers around the APIRequest constructor that can take in data (as HTTPParameters and/or HTTPBody as a json dictionary [String: Any]). For example if you would like to get user information by id, the endpoint may look like this:
open class func getUser(byId id: Int) -> APIRequest<ExampleReturnType> {
    return APIRequest<ExampleReturnType>(service: Self, endpoint: "/users", params: ["id": id], body: nil, method: .GET)
}

Using an APIService

Now that you have an APIService, you can use it make RESTful API Requests.

All the RESTful API endpoints we need to access should already be defined in our APIService, so using them is simply a matter of calling them.

Using the example service above, we can make a request to get the User associated with the id 452398:

let request = ExampleService.getUser(byId: 452398)

And subsecquently perform the APIRequest with:

request.perform(withAuthorization: nil)

However, this leaves us unable to access the response nor potential error and additionally requires multiple lines to do what is really one action. Conveniently APIManager allows us to solve this problems with simple chaining syntax. We can specify success, cancellation, and failure blocks. This new request is seen below:

ExampleService.getUser(byId: 452398)
.onSuccess { (returnValue: ReturnType) in
    // Handle Success (Background thread)
    DispatchQueue.main.async {
        // Handle Success (main thread)
    }
}
.onFailure { (error) in
    // Handle Failure (Background thread)
    DispatchQueue.main.async {
        // Handle Failure (main thread)
    }
}
.perform(withAuthorization: nil)

Support

Please open an issue for support.

Contributing

Please contribute using Github Flow. Create a branch, add commits, and open a pull request.

License

This project is licensed under the MIT License. For a full copy of this license take a look at the LICENSE file.