Skip to content

Commit 330c039

Browse files
committed
Replace PromiseKit with async/await api
1 parent 8176b16 commit 330c039

16 files changed

+141
-378
lines changed

Cartfile

Lines changed: 0 additions & 1 deletion
This file was deleted.

Cartfile.resolved

Lines changed: 0 additions & 1 deletion
This file was deleted.

Package.resolved

Lines changed: 0 additions & 16 deletions
This file was deleted.

Package.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import PackageDescription
66
let package = Package(
77
name: "SwiftJSONRPC",
88
platforms: [
9-
.macOS(.v10_12),
10-
.iOS(.v10),
11-
.tvOS(.v10),
12-
.watchOS(.v3)
9+
.macOS(.v10_15),
10+
.iOS(.v13),
11+
.tvOS(.v13),
12+
.watchOS(.v6)
1313
],
1414
products: [
1515
.library(
@@ -18,12 +18,11 @@ let package = Package(
1818
),
1919
],
2020
dependencies: [
21-
.package(url: "https://github.com/mxcl/PromiseKit.git", from: "6.13.1")
2221
],
2322
targets: [
2423
.target(
2524
name: "SwiftJSONRPC",
26-
dependencies: ["PromiseKit"],
25+
dependencies: [],
2726
path: "Sources"
2827
),
2928
.testTarget(

README.md

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
```swift
1313
import SwiftJSONRPC
14-
import PromiseKit
1514

1615
class UserService: RPCService {
17-
func vote(rating: Int) -> Promise<Int> {
18-
return invoke("vote", params: ["rating": rating])
16+
func vote(rating: Int) async throws -> Int {
17+
return try await invoke("vote", params: ["rating": rating])
1918
}
20-
21-
func create(name: String) -> Promise<UserModel> {
22-
return invoke("create", params: ["name": name])
19+
20+
func create(name: String) async throws -> UserModel {
21+
return try await invoke("create", params: ["name": name])
2322
}
2423

2524
// And other JSON-RPC methods
@@ -39,21 +38,7 @@ let client = RPCClient(url: url)
3938
let service = MyService(client: client)
4039

4140
// Perform request
42-
service.vote(rating: 5)
43-
```
44-
45-
### Result Handling
46-
47-
SwiftJSONRPC uses [PromiseKit](https://github.com/mxcl/PromiseKit) to return result.
48-
49-
```swift
50-
service.vote(rating: 5)
51-
.done { newRating in
52-
// Handle result
53-
}
54-
.catch { error in
55-
// Handle error
56-
}
41+
try await service.vote(rating: 5)
5742
```
5843

5944
#### Result Serialization
@@ -90,28 +75,26 @@ After that use this struct as `RPCService.Result` generic parameter:
9075

9176
```swift
9277
class UserService: RPCService {
93-
func create(name: String) -> Promise<UserModel> {
94-
return invoke("create", params: ["name": name])
78+
func create(name: String) async throws -> UserModel {
79+
return try await invoke("create", params: ["name": name])
9580
}
9681
}
9782
```
9883
```swift
99-
service.create(name: "testuser").done { user in
100-
print("User created with ID = \(user.id)")
101-
}
84+
let user = try await service.create(name: "testuser")
85+
print("User created with ID = \(user.id)")
10286
```
10387

10488
Using array of `Parcelable` objects is also supported:
10589

10690
```swift
10791
extension UserService {
108-
func allUsers() -> Promise<[UserModel]> {
109-
return invoke("all_users")
92+
func allUsers() async throws -> [UserModel] {
93+
return try await invoke("all_users")
11094
}
11195
}
11296
```
11397

114-
11598
## Advanced Usage
11699

117100
### Request Executor

Sources/SwiftJSONRPC/Client/RPCClient.swift

Lines changed: 66 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -7,156 +7,128 @@
77
// ----------------------------------------------------------------------------
88

99
import Foundation
10-
import PromiseKit
1110

12-
// ----------------------------------------------------------------------------
11+
open class RPCClient {
12+
13+
// MARK: - Properties
14+
15+
public var requestRetrier: RequestRetrier? = nil
16+
17+
// MARK: - Private Properties
18+
19+
private let requestExecutor: RequestExecutor
20+
21+
private let requestIdGenerator = RequestIdGenerator()
1322

14-
open class RPCClient
15-
{
16-
// MARK: - Construction
23+
// MARK: - Initialization
1724

18-
public init(requestExecutor: RequestExecutor)
19-
{
20-
// Init instance variables
25+
public init(requestExecutor: RequestExecutor) {
2126
self.requestExecutor = requestExecutor
2227
}
2328

24-
public convenience init(url: URL)
25-
{
29+
public convenience init(url: URL) {
2630
let requestExecutor = HTTPRequestExecutor(url: url)
2731
self.init(requestExecutor: requestExecutor)
2832
}
2933

30-
// MARK: - Properties
31-
32-
public var requestRetrier: RequestRetrier? = nil
33-
34-
// MARK: - Public Functions
34+
// MARK: - Public Functions
3535

36-
open func invoke<Result>(_ invocation: Invocation<Result>) -> Promise<Result>
37-
{
36+
open func invoke<Result>(_ invocation: Invocation<Result>) async throws -> Result {
3837
// Init request
3938
let request = makeRequest(invocation: invocation)
4039

41-
// Init result dispatcher
42-
let resultDispatcher = ResultDispatcher(invocation: invocation)
43-
4440
// Perform request
45-
DispatchQueue.global().async { [weak self] in
46-
self?.execute(request: request, withResultDispatcher: resultDispatcher)
47-
}
48-
49-
return resultDispatcher.promise
41+
return try await execute(request: request, with: invocation.parser)
5042
}
5143

52-
// MARK: - Private Functions
44+
// MARK: - Private Functions
5345

54-
private func makeRequest<Result>(invocation: Invocation<Result>) -> Request
55-
{
46+
private func makeRequest<Result>(invocation: Invocation<Result>) -> Request {
5647
// TODO: Support notification type calls without identifiers
57-
// Generate request indentifier
58-
let identifier = self.requestIdGenerator.next()
48+
// Generate request identifier
49+
let identifier = requestIdGenerator.next()
5950

6051
// Init request
61-
return Request(id: identifier, invocation: invocation)
52+
return Request(
53+
id: identifier,
54+
method: invocation.method,
55+
params: invocation.params
56+
)
6257
}
6358

64-
private func execute<R>(request: Request, withResultDispatcher resultDispatcher: ResultDispatcher<R>)
65-
{
66-
execute(request: request) { result in
67-
resultDispatcher.dispatch(result: result)
59+
private func execute<Result>(request: Request, with parser: AnyResultParser<Result>) async throws -> Result {
60+
return try await withCheckedThrowingContinuation { continuation in
61+
execute(request: request) { result in
62+
do {
63+
continuation.resume(returning: try result.result(with: parser))
64+
} catch {
65+
continuation.resume(throwing: error)
66+
}
67+
}
6868
}
6969
}
7070

71-
private func execute(request: Request, completionHandler: @escaping (RequestExecutorResult) -> Void)
72-
{
73-
self.requestExecutor.execute(request: request) { [weak self] result in
74-
if let instance = self,
75-
instance.shouldRetry(request: request, afterResult: result)
76-
{
77-
instance.execute(request: request, completionHandler: completionHandler)
78-
}
79-
else {
71+
private func execute(request: Request, completionHandler: @escaping (RequestExecutorResult) -> Void) {
72+
requestExecutor.execute(request: request) { [weak self] result in
73+
if let self = self,
74+
self.shouldRetry(request: request, afterResult: result) {
75+
self.execute(request: request, completionHandler: completionHandler)
76+
} else {
8077
completionHandler(result)
8178
}
8279
}
8380
}
8481

85-
private func shouldRetry(request: Request, afterResult result: RequestExecutorResult) -> Bool
86-
{
82+
private func shouldRetry(request: Request, afterResult result: RequestExecutorResult) -> Bool {
8783
let retry: Bool
8884

8985
if case .response(let response) = result,
90-
let requestRetrier = self.requestRetrier
91-
{
86+
let requestRetrier = self.requestRetrier {
9287
retry = requestRetrier.should(client: self, retryRequest: request, afterResponse: response)
93-
}
94-
else {
88+
} else {
9589
retry = false
9690
}
9791

9892
return retry
9993
}
10094

101-
// MARK: - Constants
95+
// MARK: - Constants
10296

10397
static let Version = "2.0"
10498

105-
// MARK: - Variables
106-
107-
private let requestExecutor: RequestExecutor
108-
109-
private let requestIdGenerator = RequestIdGenerator()
110-
11199
}
112100

113-
// ----------------------------------------------------------------------------
101+
private extension RequestExecutorResult {
114102

115-
extension ResultDispatcher
116-
{
117-
// MARK: - Private Functions
103+
// MARK: - Functions
118104

119-
fileprivate func dispatch(result: RequestExecutorResult)
120-
{
121-
switch result
122-
{
123-
case .response(let response):
124-
dispatch(response: response)
125-
126-
case .error(let error):
127-
dispatch(error: InvocationError.applicationError(cause: error))
128-
129-
case .cancel:
130-
dispatch(error: InvocationError.canceled)
105+
func result<Result>(with parser: AnyResultParser<Result>) throws -> Result {
106+
switch self {
107+
case .response(let response):
108+
return try result(for: response, with: parser)
109+
case .error(let error):
110+
throw InvocationError.applicationError(cause: error)
111+
case .cancel:
112+
throw InvocationError.canceled
131113
}
132114
}
133115

134-
fileprivate func dispatch(response: Response)
135-
{
136-
switch response.body
137-
{
138-
case .success(let successBody):
139-
dispatchSuccessBody(successBody)
116+
// MARK: - Private Functions
140117

141-
case .error(let error):
142-
dispatch(error: InvocationError.rpcError(error: error))
118+
private func result<Result>(for response: Response, with parser: AnyResultParser<Result>) throws -> Result {
119+
switch response.body {
120+
case .success(let successBody):
121+
return try resultForSuccessBody(successBody, with: parser)
122+
case .error(let error):
123+
throw InvocationError.rpcError(error: error)
143124
}
144125
}
145126

146-
fileprivate func dispatchSuccessBody(_ body: AnyObject)
147-
{
127+
private func resultForSuccessBody<Result>(_ body: AnyObject, with parser: AnyResultParser<Result>) throws -> Result {
148128
do {
149-
let result = try self.invocation.parser.parse(body)
150-
dispatch(result: result)
151-
}
152-
catch (let cause)
153-
{
154-
let error = InvocationError.applicationError(cause: cause)
155-
dispatch(error: error)
129+
return try parser.parse(body)
130+
} catch {
131+
throw InvocationError.applicationError(cause: error)
156132
}
157133
}
158-
159134
}
160-
161-
// ----------------------------------------------------------------------------
162-

Sources/SwiftJSONRPC/Invocation/CallbackEvent.swift

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)