JSONRPCKit

Build Status Carthage compatible CocoaPods

JSONRPCKit 是一个类型安全的 JSON-RPC 2.0 库,完全用 Swift 编写。

// Generating request JSON
let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request = Subtract(minuend: 42, subtrahend: 23)
let batch = batchFactory.create(request)
batch.requestObject // ["jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1]

// Parsing response JSON
let responseObject: Any = ["jsonrpc": "2.0", "result": 19, "id": 1]
let response = try! batch.responses(from: responseObject)
response // 19 (type of response is inferred from SubtractRequest.Response)

需求

基本用法

  1. 定义请求类型
  2. 生成请求 JSON
  3. 解析响应 JSON

定义请求类型

首先,定义一个符合 Request 协议的请求类型。

struct Subtract: JSONRPCKit.Request {
    typealias Response = Int

    let minuend: Int
    let subtrahend: Int

    var method: String {
        return "subtract"
    }

    var parameters: Any? {
        return [minuend, subtrahend]
    }

    func response(from resultObject: Any) throws -> Response {
        if let response = resultObject as? Response {
            return response
        } else {
            throw CastError(actualValue: resultObject, expectedType: Response.self)
        }
    }
}

生成请求 JSON

要生成请求 JSON,将 Request 实例传递给 BatchFactory 实例,该实例具有通用的 JSON-RPC 版本和标识符生成器。当 BatchFactory 实例接收到请求时,它会为请求生成标识符,并通过组合 id、版本、方法和参数来生成请求 JSON。

let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request1 = Subtract(minuend: 42, subtrahend: 23)
let request2 = Subtract(minuend: 23, subtrahend: 42)
let batch = batchFactory.create(request1, request2)

请求 JSON 可在 batch.requestObject 中找到。 看起来像下面这样

[
  {
    "method" : "subtract",
    "jsonrpc" : "2.0",
    "id" : 1,
    "params" : [
      42,
      23
    ]
  },
  {
    "method" : "subtract",
    "jsonrpc" : "2.0",
    "id" : 2,
    "params" : [
      23,
      42
    ]
  }
]

解析响应 JSON

假设服务器返回以下 JSON

[
  {
    "result" : 19,
    "jsonrpc" : "2.0",
    "id" : 1,
    "status" : 0
  },
  {
    "result" : -19,
    "jsonrpc" : "2.0",
    "id" : 2,
    "status" : 0
  }
]

要解析响应对象,请执行 Batch 实例的 responses(from:) 方法。 当调用 responses(from:) 时,Batch 通过比较请求 id 和响应 id 来找到相应的响应对象。 找到响应对象后,它会执行 Responseresponses(from:) 方法,以从响应对象中获取 Request.Response

let responseObject = ...
let (response1, response2) = try! batch.responses(from: responseObject)
print(response1) // 19
print(response2) // -19

通过 APIKit 使用 HTTP 传输 JSON-RPC

APIKit 是一个类型安全的网络抽象层。

定义 HTTP 请求类型

APIKit 也有一个代表 HTTP 请求的 RequestType

import APIKit

struct MyServiceRequest<Batch: JSONRPCKit.Batch>: APIKit.Request {
    let batch: Batch

    typealias Response = Batch.Responses

    var baseURL: URL {
        return URL(string: "https://api.example.com/")!
    }

    var method: HTTPMethod {
        return .post
    }

    var path: String {
        return "/"
    }

    var parameters: Any? {
        return batch.requestObject
    }

    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
        return try batch.responses(from: object)
    }
}

发送 HTTP/HTTPS 请求

let batchFactory = BatchFactory(version: "2.0", idGenerator: NumberIdGenerator())
let request1 = Subtract(minuend: 42, subtrahend: 23)
let request2 = Subtract(minuend: 23, subtrahend: 42)
let batch = batchFactory.create(request1, request2)
let httpRequest = MyServiceRequest(batch: batch)

Session.sendRequest(httpRequest) { result in
    switch result {
    case .Success(let response1, let response2):
        print(response1.count) // CountCharactersResponse
        print(response2.count) // CountCharactersResponse

    case .Failure(let error):
        print(error)
    }
}

许可证

JSONRPCKit 在 MIT 许可证下发布。