Swiftpack.co - Package - railwaymen/restler

Restler

Package Build Status Example App Build Status Coverage Status

The Restler framework has been built to use features of the newest versions of Swift. Inspiration for it is Vapor library for building Server-side with Swift. What we love is functional programming, so you can build your desired request just calling some chained functions. The main goal of the framework is to provide nice interface for making API requests the easiest as possible and the fastest as possible.

List of Content

  1. Documentation
  2. Instalation
  3. Usage
  4. Contribution

Documentation

We think that README isn't a good place for complete documentation so that's why we decided to generate it to a folder inside the framework repository. Full documentation you can find in the Documentation folder. If you're looking for a description of a specific protocol or class, we put here a list of the most important symbols.

Restler

RestlerType - it's the main protocol which should be used when it comes to mocking or using Restler's class' instance.

Request builder

All these protocols are defined in one file: RestlerRequestBuilderType

Request

Restler.Request - generic class for all request types provided by Restler.

Errors

  • Restler.Error - errors returned by Restler.
  • Restler.ErrorType - types which Restler can decode by himself. Every different type would be an unknownError.

Error parser

Instalation

Nothing is easier there - you just add the framework to the Swift Package Manager dependecies if you use one.

Otherwise you can use CocoaPods. If you use one simply add to your Podfile:

...
pod 'Restler/Core'
...

It's important to specify it with /Core! (Changed in v1.0) and call in your console:

pod install

Import the framework to the project:

import Restler

and call it!

Usage Examples

Error parser

If you don't want to add the same error to be parsed on failure of every request, simply add the error directly to the error parser of the Restler object.

restler.errorParser.decode(ErrorToDecodeOnFailure.self)

If you don't want to decode it anymore, simply stop decoding it:

restler.errorParser.stopDecoding(ErrorToDecodeOnFailure.self)

Header

Setting header values is very easy. Simply set it as a dictionary:

restler.header = [
  .contentType: "application/json",
  .cacheControl: "none",
  "customKey": "value"
]
restler.header[.cacheControl] = nil

If you're using basic authentication at "Authorization" key, simply provide username and password to header:

restler.header.setBasicAuthentication(username: "me", password: "password")

Restler calls

GET

Restler(baseURL: myBaseURL)
  .get(Endpoint.myProfile) // 1
  .query(anEncodableQueryObject) // 2
  .failureDecode(ErrorToDecodeOnFailure.self) // 3
  .setInHeader("myNewTemporaryToken", forKey: "token") // 4
  .receive(on: .main) // 5
  .decode(Profile.self) // 6
  // 7

  .subscribe(
    onSuccess: { profile in // 8
      updateProfile(with: profile)
    },
    onCompletion: { _ in // 9
      hideLoadingIndicator()
  })
  1. Makes GET request to the given endpoint.
  2. Encodes the object and puts it in query for GET request.
  3. If an error will occur, an error parser would try to decode the given type.
  4. Sets the specified value for the given key in the header only for this request.
  5. Sets dispatch queue on which completion handlers will be called to the main queue.
  6. Decodes Profile object on a successful response. If it is not optional, a failure handler can be called.
  7. Since this moment we're operating on a request, not a request builder.
  8. A handler called if Restler would successfully end request.
  9. A handler called on completion of the request whatever the result would be.

POST

Restler(baseURL: myBaseURL)
  .post(Endpoint.myProfile) // 1
  .body(anEncodableQueryObject) // 2
  .failureDecode(ErrorToDecodeOnFailure.self)
  .decode(Profile.self)

  .subscribe(
    onFailure: { error in // 3
      print("\(error)")
    },
    onCompletion: { _ in
      hideLoadingIndicator()
  })
  1. Makes POST request to the given endpoint.
  2. Encodes the object and puts it into the body of the request. Ignored if the selected request method doesn't support it.
  3. A handler called if the request has failed.

Other

Any other method call is very similar to these two, but if you have questions simply create an issue.

Restler + Combine

Restler(baseURL: myBaseURL)
  .get(Endpoint.myProfile) // 1
  .query(anEncodableQueryObject) // 2
  .publisher()? // 3
  .receive(on: DispatchQueue.main) // 4
  .map(\.data) // 5
  .decode(type: Profile.self, decoder: JSONDecoder()) // 6
  .catch { _ in Empty() } // 7
  .assign(to: \.profile, on: self) // 8
  .store(in: &subscriptions) // 9
  1. Makes GET request to the given endpoint.
  2. Encodes the object and puts it in query for GET request.
  3. Builds a request and returns publisher for Combine support.
  4. Specifies the scheduler on which to receive elements from the publisher. In this case main queue.
  5. Get Data object from DataTaskPublisher.
  6. Decodes Profile object.
  7. Handle error
  8. Assigns each element from a Publisher to a property on an object.
  9. Stores this type-erasing cancellable instance in the specified collection.

Restler + RxSwift

First of all you need to add RxRestler to your target you can do it simply in SPM. In CocoaPods you should add to your Podfile:

pod `Restler/Rx`

Then import RxRestler to every file its needed.

Restler(baseURL: myBaseURL)
  .get(Endpoint.myProfile)
  .query(anEncodableQueryObject)
  .receive(on: .main) // 1
  .decode(Profile.self) // 2
  .rx // 3
  .subscribe( // 4
    onSuccess: { print("This is my profile:", $0) },
    onError: { print("This is an error:", $0) })
  .disposed(by: bag) // 5
  1. Subscribe handlers will be called on the provided queue even if it's done with RxSwift (setting a scheduler with this property set may cause some little delay between receiving a response and handling it but the handlers will be called on the provided scheduler).
  2. Decode some type on successful response - Void, Data, or some custom object.
  3. Move request to Rx usage. This returns Single<Profile> in this case.
  4. Here we call already the RxSwift function.
  5. Remember about adding the Disposable to the DisposeBag. The networking task will be canceled automatically if the bag will deinitialize.

Contribution

If you want to contribute in this framework, simply put your pull request here.

If you have found any bug, file it in the issues.

If you would like Restler to do something else, create an issue for feature request.

Configuration

  1. Clone the project and open the project's folder in terminal.
  2. Run a configuration script: ./Scripts/configure.sh
  3. Fill configuration file in folder Restler-Example/Restler-Example/Configuration named Debug.xcconfig with needed information.
  4. Open the project in the folder Restler-Example. You can do it from terminal: open Restler-Example/Restler-Example.xcodeproj
  5. Run tests to be sure everything works properly.

Dependencies

Gems

Github

link
Stars: 1

Dependencies

Used By

Total: 0

Releases

v1.0.0 - 2020-09-11 08:23:07

Changed (Breaking changes!)

  • Deprecated functions onSuccess, onFailure, onCompletion and start. Now they all are combined into subscribe(onSuccess:onFailure:onCompletion:) Please, adjust to this deprecation as soon as possible. We'll delete the deprecated functions in the next versions.
  • Now handlers provided in the function subscribe(onSuccess:onFailure:onCompletion:) will not be called on the main thread. To stay with the previous behavior, you have to add .receive(on: .main) before calling .decode(SomeType.self). For more info take a look at the README.md file.
  • If you're using CocoaPods, you will have to change import to pod 'Restler/Core' from this version if you don't want to import RxSwift.

Added

  • Support for Combine.
  • Support for RxSwift.
  • Support for all Apple Platforms in every version supported by SwiftPM.
  • Possibility to build a URLRequest directly from the RequestBuilder.
  • Logging requests in a DEBUG build.
  • Possibility to run finish handlers on a custom dispatch queue.
  • Possibility to run task on a custom URLSession.

Version 0.6.0 - 2020-06-22 13:12:39

Added

  • Possibility of custom modifications on URLRequest.

Changed

  • The result of the start() method can be ignored now.
  • ErrorParser is a structure now instead of being a class.
  • Updated README

Bump version - 2020-04-14 13:38:58

Bump version, no changes

Make Restler public - 2020-04-14 12:43:52

Nothing changed in the framework besides it's now open-source and open publicly for usage