SimpleApiClient alternatives and similar libraries
Based on the "Reactive Programming" category.
Alternatively, view SimpleApiClient alternatives based on common mentions on social networks and blogs.
-
OpenCombine
Open source implementation of Apple's Combine framework for processing values over time. -
Tokamak
DISCONTINUED. SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms [Moved to: https://github.com/TokamakUI/Tokamak] -
Katana
DISCONTINUED. Swift Apps in a Swoosh! A modern framework for creating iOS apps, inspired by Redux. -
Interstellar
DISCONTINUED. Simple and lightweight Functional Reactive Coding in Swift for the rest of us. :large_orange_diamond: -
Verge
๐ฃ A robust Swift state-management framework designed for complex applications, featuring an integrated ORM for efficient data handling. -
VueFlux
:recycle: Unidirectional State Management Architecture for Swift - Inspired by Vuex and Flux -
RxReduce
DISCONTINUED. Lightweight framework that ease the implementation of a state container pattern in a Reactive Programming compliant way. -
LightweightObservable
๐ฌ A lightweight implementation of an observable sequence that you can subscribe to. -
ReactiveArray
An array class implemented in Swift that can be observed using ReactiveCocoa's Signals -
STDevRxExt
STDevRxExt contains some extension functions for RxSwift and RxCocoa which makes our live easy. -
RxAlamoRecord
RxAlamoRecord combines the power of the AlamoRecord and RxSwift libraries to create a networking layer that makes interacting with API's easier than ever reactively.
CodeRabbit: AI Code Reviews for Developers

* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of SimpleApiClient or a related project?
README
SimpleApiClient
A configurable api client based on Alamofire4 and RxSwift4 for iOS
Requirements
- iOS 8.0+
- Swift 4
Table of Contents
- Basic Usage
- Unwrap Response by KeyPath
- Upload File(s)
- Serial / Parallel Calls
- Retry Interval / Exponential backoff
- Call Cancellation
- Mock Response
Installation
SimpleApiClient is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'SimpleApiClient'
Basic Usage
Step 1
Configurate the api client
let config = SimpleApiClient.Config(
baseUrl: "https://api.github.com",
defaultParameters: ["foo": "bar"],
defaultHeaders: ["foo": "bar"],
timeout: 120, // default is 60s
certificatePins: [
CertificatePin(hostname: "https://api.github.com", certificateUrl: Bundle.main.url(forResource: "serverCert", withExtension: "cer")!)
],
errorMessageKeyPath: "message",
jsonDecoder: JSONDecoder(), // default is JSONDecoder()
isMockResponseEnabled: true, // default is false
logHandler: { request, response in
...
},
errorHandler: { error in
// you can centralize the handling of general error here
switch error {
case .authenticationError(let code, let message):
...
case .clientError(let code, let message):
...
case .serverError(let code, let message):
...
case .networkError(let source):
...
case .sslError(let source):
...
case .uncategorizedError(let source):
...
}
}
)
let githubClient = SimpleApiClient(config: config)
Step 2
Create the API
import SimpleApiClient
struct GetRepoApi: SimpleApi {
let user: String
let repo: String
var path: String {
return "/repos/\(user)/\(repo)"
}
var method: HTTPMethod {
return .get
}
// optional
var parameters: Parameters {
return [:]
}
// optional
var headers: HTTPHeaders {
return [:]
}
}
extension SimpleApiClient {
func getRepo(user: String, repo: String) -> Observable<Repo> {
return request(api: GetRepoApi(user: user, repo: repo))
}
}
Step 3
Use observe()
to enqueue the call, do your stuff in corresponding parameter block. All blocks run on main thread by default and are optional.
githubClient.getRepo(user: "foo", repo: "bar")
.observe(
onStart: { print("show loading") },
onEnd: { print("hide loading") },
onSuccess: { print("sucess: \($0)") },
onError: { print("error: \($0)" }
)
Model
The library uses JSONDecoder to deserialize JSON to model object, so the model should conform to Decodable or Codable
struct User: Decodable {
let name: String
let profileUrl: URL
// if the serialized name is different from the property name
private enum CodingKeys: String, CodingKey {
case name = "login"
case profileUrl = "avatar_url"
}
}
Unwrap Response by KeyPath
Sometimes the api response includes metadata that we don't need, but in order to map the response we create a wrapper class and make the function return that wrapper class. This approach leaks the implementation of service to calling code.
Assuming the response json looks like the following:
{
total_count: 33909,
incomplete_results: false,
foo: {
bar: {
items: [
{
login: "foo",
...
}
...
]
}
}
}
And you only need the items
part, implement Unwrappable
to indicate which part of response you want.
struct GetUsersApi: SimpleApi, Unwrappable {
...
var responseKeyPath: String {
return "foo.bar.items"
}
}
// then your response will be a list of User
extension SimpleApiClient {
func getUsers(query: String) -> Observable<[User]> {
return request(api: GetUsersApi(query: query))
}
}
Upload File(s)
To upload file(s), make the API implements Uploadable
to provide Multipart
s
struct UploadImageApi: SimpleApi, Uploadable {
...
var multiParts: [MultiPart] {
let multiPart = MultiPart(data: UIImageJPEGRepresentation(image, 1)!, name: "imagefile", filename: "image.jpg", mimeType: "image/jpeg")
return [multiPart]
}
}
extension SimpleApiClient {
func uploadImage(image: UIImage) -> Observable<Image> {
return request(api: UploadImageApi(image))
}
}
Serial / Parallel Calls
Serial
githubClient.foo()
.then { foo in githubClient.bar(foo.name) }
.observe(...)
Serial then Parallel
githubClient.foo()
.then { foo in githubClient.bar(foo.name) }
.thenAll { bar in
(githubClient.baz(bar.name), githubClient.qux(bar.name)) // return a tuple
}
.observe(...)
Parallel
SimpleApiClient.all(
githubApi.foo(),
githubApi.bar()
)
.observe(...)
Parallel then Serial
SimpleApiClient.all(
githubApi.foo(),
githubApi.bar()
).then { array -> // the return type is Array<Any>, you should cast them, e.g. let foo = array[0] as! Foo
githubApi.baz()
}.observe(...)
Retry Interval / Exponential backoff
githubClient.getUsers("foo")
.retry(delay: 5, maxRetryCount: 3) // retry up to 3 times, each time delays 5 seconds
.retry(exponentialDelay: 5, maxRetryCount: 3) // retry up to 3 times, each time delays 5^n seconds, where n = {1,2,3}
.observe(...)
Call Cancellation
Auto Call Cancellation
The call will be cancelled when the object is deallocated.
githubClient.getUsers("foo")
.cancel(when: self.rx.deallocated)
.observe(...)
Cancel call manually
let call = githubClient.getUsers("foo").observe(...)
call.cancel()
Mock Response
To enable response mocking, set SimpleApiClient.Config.isMockResponseEnabled
to true
and make the API implements Mockable
to provide MockResponse
.
Mock sample json data
To make the api return a successful response with provided json
struct GetUsersApi: SimpleApi, Mockable {
...
var mockResponse: MockResponse {
let file = Bundle.main.url(forResource: "get_users", withExtension: "json")!
return MockResponse(jsonFile: file)
}
}
Mock status
To make the api return a client side error with provided json
struct GetUsersApi: SimpleApi, Mockable {
...
var mockResponse: MockResponse {
let file = Bundle.main.url(forResource: "get_users_error", withExtension: "json")!
return MockResponse(jsonFile: file, status: .clientError)
}
}
the parameter jsonFile
of MockResponse
is optional, you can set the status only, then you receive empty string.
Possible Status
values:
public enum Status {
case success
case authenticationError
case clientError
case serverError
case networkError
case sslError
}
To mock a response with success status only, you should return Observable<Nothing>
.
struct DeleteRepoApi: SimpleApi, Mockable {
...
var mockResponse: MockResponse {
return MockResponse(status: .success)
}
}
extension SimpleApiClient {
func deleteRepo(id: String) -> Observable<Nothing> {
return request(api: DeleteRepoApi(id: id))
}
}
Author
jaychang0917, [email protected]
License
SimpleApiClient is available under the MIT license. See the LICENSE file for more info.
*Note that all licence references and agreements mentioned in the SimpleApiClient README section above
are relevant to that project's source code only.