Skip to content

Commit ee18e75

Browse files
committed
Use async/await instead of PromiseKit
1 parent 393db51 commit ee18e75

File tree

8 files changed

+110
-257
lines changed

8 files changed

+110
-257
lines changed

ConvAPI.podspec

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

Package.resolved

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

Package.swift

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
1-
// swift-tools-version: 5.7
1+
// swift-tools-version: 5.9
22
import PackageDescription
33

44
let package = Package(
55
name: "ConvAPI",
66
platforms: [
7-
.iOS(.v11),
7+
.iOS(.v15),
88
],
99
products: [
1010
.library(name: "ConvAPI", targets: ["ConvAPI"]),
1111
],
12-
dependencies: [
13-
.package(url: "https://github.com/mxcl/PromiseKit.git", from: "6.8.0"),
14-
.package(url: "https://github.com/PromiseKit/Foundation.git", from: "3.0.0"),
15-
],
1612
targets: [
17-
.target(name: "ConvAPI", dependencies: [
18-
.product(name: "PromiseKit", package: "PromiseKit"),
19-
.product(name: "PMKFoundation", package: "Foundation"),
20-
]),
13+
.target(name: "ConvAPI"),
2114
.testTarget(name: "ConvAPITests", dependencies: ["ConvAPI"]),
2215
]
2316
)

README.md

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ConvAPI
2-
[![](http://img.shields.io/badge/Swift-5.0-blue.svg)]() [![](http://img.shields.io/badge/iOS-10.0%2B-blue.svg)]() [![](https://img.shields.io/github/license/ChaosCoder/ConvAPI.svg)](LICENSE.md) [![Build Status](https://app.bitrise.io/app/9bd0d2e769e903f9/status.svg?token=9IwhtVc_5lq3l5PnCY9LLQ&branch=master)](https://app.bitrise.io/app/9bd0d2e769e903f9)
2+
[![](http://img.shields.io/badge/Swift-5.0-blue.svg)]() [![](http://img.shields.io/badge/iOS-15.0%2B-blue.svg)]() [![](https://img.shields.io/github/license/ChaosCoder/ConvAPI.svg)](LICENSE.md) [![Build Status](https://app.bitrise.io/app/9bd0d2e769e903f9/status.svg?token=9IwhtVc_5lq3l5PnCY9LLQ&branch=master)](https://app.bitrise.io/app/9bd0d2e769e903f9)
33

44
ConvAPI allows easy [HTTP](https://tools.ietf.org/html/rfc7231) requests in [Swift](https://swift.org) against [REST](https://en.wikipedia.org/wiki/Representational_state_transfer)-style [APIs](https://en.wikipedia.org/wiki/Application_programming_interface) with [JSON](https://www.json.org/) formatting by supporting [codable](https://developer.apple.com/documentation/swift/codable) bodies and [promised](https://github.com/mxcl/PromiseKit) responses.
55

@@ -17,11 +17,11 @@ func request<T, U, E>(method: APIMethod,
1717
params: [String: Any]?,
1818
body: T?,
1919
error: E.Type,
20-
decorator: ((inout URLRequest) -> Void)?) -> Promise<U>
20+
decorator: ((inout URLRequest) -> Void)?) async throws -> U
2121
```
2222
where `T: Encodable, U: Decodable, E: (Error & Decodable)` at its core.
2323

24-
This method allows you to request a resource from an API specifying the
24+
This method allows you to asynchronously request a resource from an API specifying the
2525
- method (*e.g. `GET`*),
2626
- baseURL,
2727
- resource URI (*e.g. `/users/42`*),
@@ -45,11 +45,8 @@ struct User: Codable {
4545

4646
let api = ConvAPI()
4747
let baseURL = URL(string: "https://jsonplaceholder.typicode.com")!
48-
firstly { () -> Promise<User> in
49-
api.request(method: .GET, baseURL: baseURL, resource: "/users/1", error: ConvAPIError.self)
50-
}.done { user in
51-
print(user) // User(id: 1, name: "Leanne Graham")
52-
}
48+
let user: User = try await api.request(method: .GET, baseURL: baseURL, resource: "/users/1", error: ConvAPIError.self)
49+
print(user) // User(id: 1, name: "Leanne Graham")
5350
```
5451

5552
### Specifying an error
@@ -62,32 +59,19 @@ struct MyAPIError: Error, Codable {
6259
let message: String
6360
}
6461

65-
firstly { () -> Promise<User> in
66-
api.request(method: .GET, baseURL: baseURL, resource: "/users/1", error: MyAPIError.self)
67-
}.done { user in
62+
do {
63+
let user: User = try await api.request(method: .GET, baseURL: baseURL, resource: "/users/1", error: MyAPIError.self)
6864
// [...]
69-
}.catch { error in
65+
} catch {
7066
switch error {
7167
case let error as MyAPIError: print(error.code)
7268
default: break // Request error, network down, etc.
7369
}
7470
}
7571
```
7672

77-
## Install
78-
79-
### Cocoapods
80-
81-
```ruby
82-
pod 'ConvAPI'
83-
```
84-
8573
### Swift Package Manager
8674

8775
```swift
8876
.package(url: "https://github.com/ChaosCoder/ConvAPI.git", from: "1.0.0")
8977
```
90-
91-
## Acknowledgments
92-
93-
This uses [mxcl/PromiseKit](https://github.com/mxcl/PromiseKit) as a dependency.

Sources/ConvAPI/API.swift

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//
88

99
import Foundation
10-
import PromiseKit
1110

1211
public protocol API {
1312

@@ -21,7 +20,7 @@ public protocol API {
2120
params: [String: Any]?,
2221
body: T?,
2322
error: E.Type,
24-
decorator: ((inout URLRequest) -> Void)?) -> Promise<U> where T: Encodable, U: Decodable, E: (Error & Decodable)
23+
decorator: ((inout URLRequest) -> Void)?) async throws -> U where T: Encodable, U: Decodable, E: (Error & Decodable)
2524
}
2625

2726
public extension API {
@@ -32,16 +31,16 @@ public extension API {
3231
headers: [String: String]? = nil,
3332
params: [String: Any]? = nil,
3433
error: E.Type,
35-
decorator: ((inout URLRequest) -> Void)? = nil) -> Promise<U> where U: Decodable, E: Decodable & Error {
34+
decorator: ((inout URLRequest) -> Void)? = nil) async throws -> U where U: Decodable, E: Decodable & Error {
3635

37-
return request(method: method,
38-
baseURL: baseURL,
39-
resource: resource,
40-
headers: headers,
41-
params: params,
42-
body: nil as Bool?,
43-
error: error,
44-
decorator: decorator)
36+
return try await request(method: method,
37+
baseURL: baseURL,
38+
resource: resource,
39+
headers: headers,
40+
params: params,
41+
body: nil as Bool?,
42+
error: error,
43+
decorator: decorator)
4544
}
4645

4746
func request<T, E>(method: APIMethod,
@@ -51,23 +50,24 @@ public extension API {
5150
params: [String: Any]? = nil,
5251
body: T?,
5352
error: E.Type,
54-
decorator: ((inout URLRequest) -> Void)? = nil) -> Promise<Void> where T: Encodable, E: Decodable & Error {
55-
let promise: Promise<EmptyResponse> = request(method: method,
56-
baseURL: baseURL,
57-
resource: resource,
58-
headers: headers,
59-
params: params,
60-
body: body,
61-
error: error,
62-
decorator: decorator)
63-
return promise.asVoid().recover({ error in
53+
decorator: ((inout URLRequest) -> Void)? = nil) async throws -> Void where T: Encodable, E: Decodable & Error {
54+
do {
55+
let _: EmptyResponse = try await request(method: method,
56+
baseURL: baseURL,
57+
resource: resource,
58+
headers: headers,
59+
params: params,
60+
body: body,
61+
error: error,
62+
decorator: decorator)
63+
} catch {
6464
if let requestError = error as? RequestError,
65-
case .emptyResponse = requestError {
65+
case .emptyResponse = requestError {
6666
return ()
6767
} else {
6868
throw error
6969
}
70-
})
70+
}
7171
}
7272

7373
func request<E>(method: APIMethod,
@@ -76,22 +76,23 @@ public extension API {
7676
headers: [String: String]? = nil,
7777
params: [String: Any]? = nil,
7878
error: E.Type,
79-
decorator: ((inout URLRequest) -> Void)? = nil) -> Promise<Void> where E: Decodable & Error {
80-
let promise: Promise<EmptyResponse> = request(method: method,
81-
baseURL: baseURL,
82-
resource: resource,
83-
headers: headers,
84-
params: params,
85-
body: nil as Bool?,
86-
error: error,
87-
decorator: decorator)
88-
return promise.asVoid().recover({ error in
79+
decorator: ((inout URLRequest) -> Void)? = nil) async throws -> Void where E: Decodable & Error {
80+
do {
81+
let _: EmptyResponse = try await request(method: method,
82+
baseURL: baseURL,
83+
resource: resource,
84+
headers: headers,
85+
params: params,
86+
body: nil as Bool?,
87+
error: error,
88+
decorator: decorator)
89+
} catch {
8990
if let requestError = error as? RequestError,
90-
case .emptyResponse = requestError {
91+
case .emptyResponse = requestError {
9192
return ()
9293
} else {
9394
throw error
9495
}
95-
})
96+
}
9697
}
9798
}

Sources/ConvAPI/AsynchronousRequester.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@
77
//
88

99
import Foundation
10-
import PromiseKit
11-
#if canImport(PMKFoundation)
12-
import PMKFoundation
13-
#endif
1410

1511
public protocol AsynchronousRequester {
16-
func dataTask(_: PMKNamespacer, with convertible: URLRequestConvertible) -> Promise<(data: Data, response: URLResponse)>
12+
func data(
13+
for request: URLRequest,
14+
delegate: (URLSessionTaskDelegate)?
15+
) async throws -> (Data, URLResponse)
1716
}
1817

1918
extension URLSession: AsynchronousRequester {}

Sources/ConvAPI/ConvAPI.swift

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//
88

99
import Foundation
10-
import PromiseKit
1110

1211
struct ConvAPIError: Error, Codable {
1312
let type: String
@@ -68,15 +67,11 @@ public class ConvAPI: API {
6867
params: [String: Any]? = nil,
6968
body: T? = nil,
7069
error: E.Type,
71-
decorator: ((inout URLRequest) -> Void)? = nil) -> Promise<U> where T: Encodable, U: Decodable, E: (Error & Decodable) {
72-
return firstly { () -> Promise<(data: Data, response: URLResponse)> in
73-
let data = try body.map { try encoder.encode($0) }
74-
let task = try request(method: method, baseURL: baseURL, resource: resource, headers: headers, params: params, body: data, decorator: decorator)
75-
76-
return requester.dataTask(.promise, with: task)
77-
}.map { data, response -> U in
78-
return try self.parseResponse(data: data, response: response, error: error)
79-
}
70+
decorator: ((inout URLRequest) -> Void)? = nil) async throws -> U where T: Encodable, U: Decodable, E: (Error & Decodable) {
71+
let bodyData = try body.map { try encoder.encode($0) }
72+
let task = try request(method: method, baseURL: baseURL, resource: resource, headers: headers, params: params, body: bodyData, decorator: decorator)
73+
let (data, response) = try await requester.data(for: task, delegate: nil)
74+
return try parseResponse(data: data, response: response, error: error)
8075
}
8176

8277
private func request(method: APIMethod = .GET,
@@ -129,14 +124,14 @@ public class ConvAPI: API {
129124
guard !data.isEmpty else {
130125
throw RequestError.emptyErrorResponse(httpStatusCode: httpResponse.statusCode)
131126
}
132-
let appError = try self.decoder.decode(E.self, from: data)
127+
let appError = try decoder.decode(E.self, from: data)
133128
throw appError
134129
}
135130

136131
guard !data.isEmpty else {
137132
throw RequestError.emptyResponse
138133
}
139134

140-
return try self.decoder.decode(U.self, from: data)
135+
return try decoder.decode(U.self, from: data)
141136
}
142137
}

0 commit comments

Comments
 (0)