Skip to content

Commit fa5881d

Browse files
committed
Merge pull request #8 from ReactKit/refactor
Ver 2.0.0: Rename then/catch to then/success/failure.
2 parents 7acd511 + 79dfe36 commit fa5881d

File tree

6 files changed

+243
-328
lines changed

6 files changed

+243
-328
lines changed

README.md

+75-90
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@ SwiftTask
55

66
![SwiftTask](Screenshots/diagram.png)
77

8+
### Ver 2.0.0 Changelog (2014/11/18)
9+
10+
- `task.progress()`'s `progressClosure` type changed from `Progress -> Void` to `(oldProgress: Progress?, newProgress: Progress) -> Void`
11+
- `task.then(fulfilledClosure)` is renamed to `task.success()`
12+
- `task.catch(catchClosure)` is renamed to `task.failure()`
13+
- `task.then()` is no longer used for fulfilled-only handling (this will improve Swift type-inference)
14+
815

916
## Example
1017

1118
### Basic
1219

1320
```swift
1421
// define task
15-
let task = Task<Float, String, NSError> { (progress, fulfill, reject, configure) in
22+
let task = Task<Float, String, NSError> { progress, fulfill, reject, configure in
1623

1724
player.doSomethingWithProgress({ (progressValue: Float) in
1825
progress(progressValue) // optional
@@ -38,10 +45,10 @@ let task = Task<Float, String, NSError> { (progress, fulfill, reject, configure)
3845

3946
}
4047

41-
// set then & catch
42-
task.then { (value: String) -> Void in
48+
// set onSuccess & onFailure
49+
task.onSuccess { (value: String) -> Void in
4350
// do something with fulfilled value
44-
}.catch { (error: NSError?, isCancelled: Bool) -> Void in
51+
}.onFailure { (error: NSError?, isCancelled: Bool) -> Void in
4552
// do something with rejected error
4653
}
4754

@@ -65,16 +72,17 @@ One of the best example would be [Alamofire](https://github.com/Alamofire/Alamof
6572

6673
```swift
6774
typealias Progress = (bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
75+
typealias AlamoFireTask = Task<Progress, String, NSError>
6876

6977
// define task
70-
let task = Task<Progress, String, NSError> { (progress, fulfill, reject, configure) in
78+
let task = AlamoFireTask { progress, fulfill, reject, configure in
7179

7280
Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: somewhere)
73-
.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
81+
.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
7482

7583
progress((bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) as Progress)
7684

77-
}.response { (request, response, data, error) in
85+
}.response { request, response, data, error in
7886

7987
if let error = error {
8088
reject(error)
@@ -88,15 +96,15 @@ let task = Task<Progress, String, NSError> { (progress, fulfill, reject, configu
8896
return
8997
}
9098

91-
// set progress & then
92-
task.progress { progress in
99+
// set onProgress & onComplete
100+
task.onProgress { (oldProgress: Progress?, newProgress: Progress) in
93101

94-
println("\(progress.bytesWritten)")
95-
println("\(progress.totalBytesWritten)")
96-
println("\(progress.totalBytesExpectedToWrite)")
102+
println("\(newProgress.bytesWritten)")
103+
println("\(newProgress.totalBytesWritten)")
104+
println("\(newProgress.totalBytesExpectedToWrite)")
97105

98-
}.then { (value: String) -> Void in
99-
// do something with fulfilled value
106+
}.onComplete { (value: String?, errorInfo: AlamoFireTask.ErrorInfo?) -> Void in
107+
// do something with fulfilled value or rejected errorInfo
100108
}
101109
```
102110

@@ -107,10 +115,10 @@ For more examples, please see XCTest cases.
107115

108116
### Task.init(closure:)
109117

110-
Define your `task` inside `closure`.
118+
Define your `task` inside `initClosure`.
111119

112120
```swift
113-
let task = Task<Float, NSString?, NSError> { (progress, fulfill, reject, configure) in
121+
let task = Task<Float, NSString?, NSError> { progress, fulfill, reject, configure in
114122

115123
player.doSomethingWithCompletion { (value: NSString?, error: NSError?) in
116124
if error == nil {
@@ -123,9 +131,9 @@ let task = Task<Float, NSString?, NSError> { (progress, fulfill, reject, configu
123131
}
124132
```
125133

126-
In order to pipeline future `task.value` or `task.errorInfo` (tuple of `(error: Error?, isCancelled: Bool)`) via `then` and `catch` methods, you have to call `fulfill(value)` and `reject(error)` inside closure.
134+
In order to pipeline future `task.value` or `task.errorInfo` (tuple of `(error: Error?, isCancelled: Bool)`) via `onComplete()`/`onSuccess()`/`onFailure()`, you have to call `fulfill(value)` and/or `reject(error)` inside `initClosure`.
127135

128-
Optionally, you can call `progress(progressValue)` multiple times before calling `fulfill`/`reject` to transfer `progressValue` outside of the closure, notifying it to `task` itself.
136+
Optionally, you can call `progress(progressValue)` multiple times before calling `fulfill`/`reject` to transfer `progressValue` outside of the `initClosure`, notifying it to `task` itself.
129137

130138
To add `pause`/`resume`/`cancel` functionality to your `task`, use `configure` to wrap up the original one.
131139

@@ -142,117 +150,94 @@ configure.cancel = { [weak player] in
142150
}
143151
```
144152

145-
### task.progress(_ progressClosure:) -> task
153+
### task.onProgress(_ progressClosure:) -> task
146154

147155
```swift
148-
task.progress { (progressValue: Progress) in
149-
println(progressValue)
156+
task.onProgress { (oldValue: Progress?, newValue: Progress) in
157+
println(newValue)
150158
return
151-
}.then { ... }
159+
}.onSuccess { ... }
152160
```
153161

154-
`task.progress(progressClosure)` will add `progressClosure` to observe `progressValue` which is notified from inside previous init-closure. This method will return same task, so it is useful to chain with forthcoming `then` and `catch`.
155-
156-
157-
### task.then(_ closure:) -> newTask
162+
`task.onProgress(progressClosure)` will add `progressClosure` to observe `progressValue` which is notified from inside previous `initClosure`. This method will return **same task**, so it is useful to chain with forthcoming `onComplete`/`onSuccess`/`onFailure`.
158163

159-
`task.then(closure)` will return a new task which behaves differently depending on what kind of `closure` is passed in.
160-
161-
1. `closure` used for **fulfilled only**
162-
2. `closure` used for both **fulfilled & rejected**
163-
164-
#### 1. closure used for fulfilled only = `fulfilledClosure`
165-
166-
`fulfilledClosure` will be invoked only when `task` is only *fulfilled*.
167-
168-
This case is similar to JavaScript's `promise.then(onFulfilled)`.
164+
### task.onComplete(_ completeClosure:) -> newTask
169165

170-
- `fulfilledClosure: Value -> Value2` (flow: *task => newTask*)
171-
172-
```swift
173-
// task will be fulfilled with value "Hello"
174-
175-
task.then { (value: String) -> String in
176-
return "\(value) World" // string value returns new string
177-
}.then { (value: String) -> Void in
178-
println("\(value)") // Hello World
179-
return"
180-
}
181-
```
182-
183-
- `fulfilledClosure: Value -> Task` (flow: *task => task2 => newTask*)
184-
185-
```swift
186-
// task will be fulfilled with value "Hello"
187-
// task2 will be fulfilled with value "\(value) Swift"
188-
189-
task.then { (value: String) -> Task<Float, String, NSError> in
190-
let task2 = ... // fulfilling "\(value) Swift"
191-
return task2
192-
}.then { (value: String) -> Void in
193-
println("\(value)") // Hello Swift
194-
return"
195-
}
196-
```
197-
198-
#### 2. closure for both fulfilled & rejected = `thenClosure`
199-
200-
In this case, `thenClosure` will be invoked when `task` is either *fulfilled* or *rejected*. This means, `thenClosure` is mostly called in future compared to `fulfilledClosure`, which is invoked only when *fulfilled*.
166+
`task.onComplete(completeClosure)` will return a new task where `completeClosure` will be invoked when `task` is either **fulfilled** or **rejected**.
201167

202168
This case is similar to JavaScript's `promise.then(onFulfilled, onRejected)`.
203169

204-
- `thenClosure: (Value?, ErrorInfo?) -> Value2` (flow: *task => newTask*)
170+
`completeClosure` can be two types of closure form:
171+
172+
1. `completeClosure: (Value?, ErrorInfo?) -> Value2` (flow: *task => newTask*)
205173

206174
```swift
207-
// task will be fulfilled with value "Hello"
175+
// let task will be fulfilled with value "Hello"
208176

209-
task.then { (value: String?, errorInfo: ErrorInfo?) -> String in
177+
task.onComplete { (value: String?, errorInfo: ErrorInfo?) -> String in
210178
// nil-check to find out whether task is fulfilled or rejected
211179
if errorInfo == nil {
212-
return "\(value) World" // string value returns new string
180+
return "\(value!) World"
213181
}
214182
else {
215-
return "\(value) Error"
183+
return "\(value!) Error"
216184
}
217-
}.then { (value: String) -> Void in
185+
}.onSuccess { (value: String) -> Void in
218186
println("\(value)") // Hello World
219187
return"
220188
}
221189
```
222190
223-
- `thenClosure: (Value?, ErrorInfo?) -> Task` (flow: *task => task2 => newTask*)
191+
2. `completeClosure: (Value?, ErrorInfo?) -> Task` (flow: *task => task2 => newTask*)
224192
225193
```swift
226-
// task will be fulfilled with value "Hello"
227-
// task2 will be fulfilled with value "\(value) Swift"
194+
// let task will be fulfilled with value "Hello"
228195
229-
task.then { (value: String) -> Task<Float, String, NSError> in
196+
task.onComplete { (value: String?, errorInfo: ErrorInfo?) -> Task<Float, String, NSError> in
230197
if errorInfo == nil {
231-
let task2 = ... // fulfilling "\(value) Swift"
198+
// let task2 will be fulfilled with value "\(value!) Swift"
199+
let task2 = ...
232200
return task2
233201
}
234202
else {
235203
return someOtherTask
236204
}
237-
}.then { (value: String) -> Void in
205+
}.onSuccess { (value: String) -> Void in
238206
println("\(value)") // Hello Swift
239207
return"
240208
}
241209
```
242210

243-
### task.catch(_ catchClosure:) -> newTask
211+
### task.onSuccess(_ successClosure:) -> newTask
212+
213+
Similar to `onComplete()` method, `task.onSuccess(successClosure)` will return a new task, but this time, `successClosure` will be invoked when task is **only fulfilled**.
214+
215+
This case is similar to JavaScript's `promise.then(onFulfilled)`.
216+
217+
```swift
218+
// let task will be fulfilled with value "Hello"
219+
220+
task.onSuccess { (value: String) -> String in
221+
return "\(value) World"
222+
}.onSuccess { (value: String) -> Void in
223+
println("\(value)") // Hello World
224+
return"
225+
}
226+
```
227+
228+
### task.onFailure(_ failureClosure:) -> newTask
244229
245-
Similar to `task.then(fulfilledClosure)` for fulfilled only, `task.catch(catchClosure)` will invoke `catchClosure` only when `task` is either *rejected* or *cancelled*.
230+
Just the opposite of `onSuccess()`, `task.onFailure(failureClosure)` will return a new task where `failureClosure` will be invoked when task is **only rejected/cancelled**.
246231
247232
This case is similar to JavaScript's `promise.then(undefined, onRejected)` or `promise.catch(onRejected)`.
248233
249234
```swift
250-
// task will be rejected with error "Oh My God"
235+
// let task will be rejected with error "Oh My God"
251236
252-
task.then { (value: String) -> Void in
237+
task.onSuccess { (value: String) -> Void in
253238
println("\(value)") // never reaches here
254239
return
255-
}.catch { (error: NSError?, isCancelled: Bool) -> Void in
240+
}.onFailure { (error: NSError?, isCancelled: Bool) -> Void in
256241
println("\(error!)") // Oh My God
257242
return
258243
}
@@ -262,24 +247,24 @@ task.then { (value: String) -> Void in
262247
263248
`Task.all(tasks)` is a new task that performs all `tasks` simultaneously and will be:
264249
265-
- fulfilled when **all tasks will be fulfilled**
266-
- rejected when **any of the task will be rejected**
250+
- fulfilled when **all tasks are fulfilled**
251+
- rejected when **any of the task is rejected**
267252
268253
### Task.any(_ tasks:) -> newTask
269254
270255
`Task.any(tasks)` is an opposite of `Task.all(tasks)` which will be:
271256
272-
- fulfilled when **any of the task will be fulfilled**
273-
- rejected when **all tasks will be rejected**
257+
- fulfilled when **any of the task is fulfilled**
258+
- rejected when **all tasks are rejected**
274259
275260
### Task.some(_ tasks:) -> newTask
276261
277-
`Task.some(tasks)` is a new task that performs all `tasks` without internal rejection, and is fulfilled with given `tasks`'s fulfilled values. Note that this new task will also become *fulfilled* with empty value-array, even though all `tasks` are rejected.
262+
`Task.some(tasks)` is a new task that performs all `tasks` without internal rejection, and is fulfilled with given `tasks`'s fulfilled values. Note that this new task **will be fulfilled with empty value-array, even though all `tasks` are rejected.**
278263
279264
280265
## Related Articles
281266
282-
- [SwiftTask(Promise拡張)を使う - Qiita](http://qiita.com/inamiy/items/0756339aee35849384c3) (Japanese)
267+
- [SwiftTask(Promise拡張)を使う - Qiita](http://qiita.com/inamiy/items/0756339aee35849384c3) (Japanese, ver 1.0.0)
283268
284269
285270
## Licence

0 commit comments

Comments
 (0)