/SwiftJSONRPC

Primary LanguageSwiftMIT LicenseMIT

SwiftJSONRPC

CI Status

Usage

Defining a Service

import SwiftJSONRPC

class UserService: JSONRPCService {
    func vote(rating: Int) -> ResultProvider<Int> {
        return invoke("vote", params: ["rating": rating])
    }
    
    func create(name: String) -> ResultProvider<UserModel> {
        return invoke("create", params: ["name": name])
    }

    // And other JSON-RPC methods
}

You can define as many services as you want depending on your requirements.

Making a Request

// Init JSON-RPC client
let url = URL(string: "http://example.com/rpc")!
let client = RPCClient(url: url)

// Init JSON-RPC service
let service = MyService(client: client)

// Perform request
service.vote(rating: 5)

Result Handling

service.vote(rating: 5).result { newRating in
    // Handle result
}

SwiftJSONRPC contains five different invocation callback types.

Result
func result(queue: ResultQueue = .background, block: @escaping (Result) -> Void) -> Self

Called on success result. Include generic response data type that you defined in RPCService subclass.

Error
func error(queue: ResultQueue = .background, block: @escaping (RPCError) -> Void) -> Self

Called on error result. Include instance of RPCError type.

Cancel
func cancel(queue: ResultQueue = .background, block: @escaping () -> Void) -> Self

Called if invocation was cancelled by calling cancel() method.

Start
func start(queue: ResultQueue = .background, block: @escaping () -> Void) -> Self

Called before performing invocation. Can be used for starting loading animation.

Finish
func finish(queue: ResultQueue = .background, block: @escaping () -> Void) -> Self

Called after performing invocation. In all cases including canceling. Can be used for stopping loading animation.

Chained Invocation Callbacks

Invocation callbacks can be chained:

service.vote(rating: 5)
    .result { newRating in
        // Handle result
    }
    .error { error in
        // Handle error
    }
    .start {
        // Setup activity indicator
    }
    .finish {
        // Remove activity indicator
    }

Invocation Callbacks Queue

By default invocation callback called on background queue. But you can specify custom queue for each callback:

service.vote(rating: 5)
    .result(queue: .background) { newRating in
        // Handle result
    }
    .error(queue: .main) { error in
        // Handle error
    }

Use one of available queue types:

enum ResultQueue
{
    case main
    case background
    case custom(queue: DispatchQueue)
}

Result Serialization

SwiftJSONRPC provides built-in result serialization for Int, String, Bool types.

Parcelable Protocol

To serialize your custom type result from JSON you can implement Parcelable protocol.

protocol Parcelable {
    init(params: [String: Any]) throws
}

For example:

struct UserModel: Parcelable {
    let id: String
    let name: String
    
    required init(params: [String: Any]) throws {
        // Parse params to struct
        // ...
    }
}

You can use libraries like ObjectMapper, MAPPER or other to adapt Parcelable protocol. Or you can adapt Swift 4 Decodable.

After that use this struct as RPCService.Result generic parameter:

class UserService: JSONRPCService {
    func create(name: String) -> ResultProvider<UserModel> {
        return invoke("create", params: ["name": name])
    }
}
service.create(name: "testuser").result { user in
    print("User created with ID = \(user.id)")
}

Using array of Parcelable objects is also supported:

extension UserService {
    func allUsers() -> ResultProvider<[UserModel]> {
        return invoke("all_users")
    }
}

Advanced Usage

Request Executor

Requirements

Installation

SwiftJSONRPC is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "SwiftJSONRPC"

ToDo

  • Add support for notification request object without an "id" member.

Author

Denis Kolyasev, kolyasev@gmail.com

License

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