Swiftpack.co - Package - apploft/APLNetworkLayer

NetworkLayer

APLNetworkLayer is a convenient interface for Apple's network framework that provides commonly used features.

This network layer is a wrapper for Apple's network classes and functions that allows to use it conveniently made with Swift. It provides all common features needed for network calls in iOS development.

List of features of the APLNetworkLayer:

  • ☑ Requests can be created with a base URL + relative URL or an absolute URL
  • ☑ Create different types of requests: GET, POST, PUT, DELETE
  • ☑ Set a global request timeout or a specific timeout for individual requests
  • ☑ Built with interfaces to be mockable for testing
  • ☑ Accept-Language header is created of the preferred languages of the device by default
  • ☑ Automatic retry of the requests if they failed
  • ☑ Provides an interface to perform authentication, token refresh or similar tasks
  • ☑ Observer on network reachability and status
  • ☑ No usage of external libraries, no dependencies
  • ☑ Convenience request warpper allowing PromiseKit-style completion handler chaining

Table of Contents

Installation

Swift Package

Just integrate the APLNetworkLayer via Xcode 11 - that's it!

Usage

Create a client configuration and an HTTP client with the HTTP factory:

guard let baseUrl = URL(string: "https://example.com/example") else { return }

// example for default header, optional parameter
let defaultHeader = ["Application-Id": "123456Abc"]

guard let clientConfiguration = HTTPFactory.createConfiguration(baseURL: baseUrl, defaultHeader: defaultHeader) else { return }

let httpClient = HTTPFactory.createClient(configuration: clientConfiguration)

Once the client has been created it can be used to create and execute HTTP requests:

guard let request = httpClient.GETRequest(relativeUrl: relativeUrl) else {
    let error = NSError(domain: "GetRequest", code: 0, userInfo: ["description": "Could not create get request with relative url \(relativeUrl)."])
    completion(HTTPResult.failure(error))
    return
}
 
let task = httpClient.createHTTPTask(urlRequest: request.urlRequest) { [weak self] (result: APLNetworkLayer.HTTPResult<HTTPResponse>) in
    switch result {
    case .success(let httpResponse):
        self?.handleSuccess(httpResponse: httpResponse, completion: completion)
    case .failure(let error):
        completion(Result.failure(error))
    }
}

Or create and execute the request at once:

let task = httpClient.GET(relativeUrl: relativeUrl) { [weak self] (result: APLNetworkLayer.HTTPResult<HTTPResponse>) in
    switch result {
    case .success(let httpResponse):
        self?.handleSuccess(httpResponse: httpResponse, completion: completion)
    case .failure(let error):
        completion(Result.failure(error))
    }
}

Using of the request convenience methods

The user has to make sure the used range make sense and do not overlap etc.


httpClient.GET(relativeUrl: "...")
          .statusCodeSuccess { (data, _) in
    // handle data on success 
}.catch { (data, _, _) in
    // on any client or server error execute this block
}.start()

httpClient.GET(relativeUrl: "...)
          .statusCode(200) { // on status code 200 execute this block }
          .statusCode(401) { // on status code 401 execute this block }
          .statusCode(..<410) { // on all status codes uo to 410 execute this block }
          .statusCode(500...599) { // on status codes between 500 and 599 execute this block }
          .anyStatusCode() { // on any status code not captured by other handlers execute this block }
          .catch { // called on any error network or http status code within 400-599  }           
          .start()

This can also be done with absolute URLs and different types of requests. You are able to fully configure all parameters of the client configuration and the requests.

Architecture

License

APLNetworkLayer is available under the MIT license. See the LICENSE file for more info.

Github

link
Stars: 4

Dependencies

Used By

Total: 0

Releases

New HTTPTaskDelegate Method for Internet Connectivity - 2020-06-19 09:07:44

As you never really know whether you are offline or not unless you try to actually send a network request, provide a new HTTPTaskDelegate method indicating that a httpTask is currently waiting for network connectivity.

This can be used to visually hint the user that the application is currently unable to load data but still trying to.

The situation is resolved (in other words, you are connected again) if the task's didReceiveResponse method is called (which means the HTTP headers were received).

A further improvement would be to map this to an (observable?) property on the HTTPTask (like isWaitingForConnectivity), but this is out of scope for this release.