First release to App Store

This commit is contained in:
Patrick McDonagh
2018-07-02 10:33:17 -05:00
parent 2e08234eef
commit 929221c9af
177 changed files with 31294 additions and 4255 deletions

View File

@@ -49,8 +49,8 @@ target "Change Me!" do
end
```
PromiseKit 6, 5 and 4 support Xcode 8.3, 9.0, 9.1, 9.2 and 9.3; Swift 3.1,
3.2, 3.3, 4.0 and 4.1 ; iOS, macOS, tvOS, watchOS, Linux and Android; CocoaPods,
PromiseKit 6, 5 and 4 support Xcode 8.3, 9.x and 10.0; Swift 3.1,
3.2, 3.3, 4.0, 4.1 and 4.2 ; iOS, macOS, tvOS, watchOS, Linux and Android; CocoaPods,
Carthage and SwiftPM; ([CI Matrix](https://travis-ci.org/mxcl/PromiseKit)).
For Carthage, SwiftPM, etc., or for instructions when using older Swifts or
@@ -149,7 +149,7 @@ func makeUrlRequest() throws -> URLRequest {
rq.httpMethod = "POST"
rq.addValue("application/json", forHTTPHeaderField: "Content-Type")
rq.addValue("application/json", forHTTPHeaderField: "Accept")
rq.httpBody = try JSONSerialization.jsonData(with: obj)
rq.httpBody = try JSONEncoder().encode(obj)
return rq
}
```

View File

@@ -85,12 +85,17 @@ class EmptyBox<T>: Box<T> {
extension Optional where Wrapped: DispatchQueue {
func async(_ body: @escaping() -> Void) {
@inline(__always)
func async(flags: DispatchWorkItemFlags?, _ body: @escaping() -> Void) {
switch self {
case .none:
body()
case .some(let q):
q.async(execute: body)
if let flags = flags {
q.async(flags: flags, execute: body)
} else {
q.async(execute: body)
}
}
}
}

View File

@@ -21,7 +21,7 @@ public extension CatchMixin {
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
*/
@discardableResult
func `catch`(on: DispatchQueue? = conf.Q.return, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) -> Void) -> PMKFinalizer {
func `catch`(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) -> Void) -> PMKFinalizer {
let finalizer = PMKFinalizer()
pipe {
switch $0 {
@@ -29,7 +29,7 @@ public extension CatchMixin {
guard policy == .allErrors || !error.isCancelled else {
fallthrough
}
on.async {
on.async(flags: flags) {
body(error)
finalizer.pending.resolve(())
}
@@ -70,7 +70,7 @@ public extension CatchMixin {
- Parameter body: The handler to execute if this promise is rejected.
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
*/
func recover<U: Thenable>(on: DispatchQueue? = conf.Q.map, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> U) -> Promise<T> where U.T == T {
func recover<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> U) -> Promise<T> where U.T == T {
let rp = Promise<U.T>(.pending)
pipe {
switch $0 {
@@ -78,7 +78,7 @@ public extension CatchMixin {
rp.box.seal(.fulfilled(value))
case .rejected(let error):
if policy == .allErrors || !error.isCancelled {
on.async {
on.async(flags: flags) {
do {
let rv = try body(error)
guard rv !== rp else { throw PMKError.returnedSelf }
@@ -97,23 +97,21 @@ public extension CatchMixin {
/**
The provided closure executes when this promise rejects.
This variant of `recover` requires the handler to return a Guarantee, thus it returns a Guarantee itself and your closure cannot `throw`.
Note it is logically impossible for this to take a `catchPolicy`, thus `allErrors` are handled.
- Note it is logically impossible for this to take a `catchPolicy`, thus `allErrors` are handled.
- Parameter on: The queue to which the provided closure dispatches.
- Parameter body: The handler to execute if this promise is rejected.
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
*/
@discardableResult
func recover(on: DispatchQueue? = conf.Q.map, _ body: @escaping(Error) -> Guarantee<T>) -> Guarantee<T> {
func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(Error) -> Guarantee<T>) -> Guarantee<T> {
let rg = Guarantee<T>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
rg.box.seal(value)
case .rejected(let error):
on.async {
on.async(flags: flags) {
body(error).pipe(to: rg.box.seal)
}
}
@@ -138,10 +136,10 @@ public extension CatchMixin {
- Parameter body: The closure that executes when this promise resolves.
- Returns: A new promise, resolved with this promises resolution.
*/
func ensure(on: DispatchQueue? = conf.Q.return, _ body: @escaping () -> Void) -> Promise<T> {
func ensure(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping () -> Void) -> Promise<T> {
let rp = Promise<T>(.pending)
pipe { result in
on.async {
on.async(flags: flags) {
body()
rp.box.seal(result)
}
@@ -167,10 +165,10 @@ public extension CatchMixin {
- Parameter body: The closure that executes when this promise resolves.
- Returns: A new promise, resolved with this promises resolution.
*/
func ensureThen(on: DispatchQueue? = conf.Q.return, _ body: @escaping () -> Guarantee<Void>) -> Promise<T> {
func ensureThen(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping () -> Guarantee<Void>) -> Promise<T> {
let rp = Promise<T>(.pending)
pipe { result in
on.async {
on.async(flags: flags) {
body().done {
rp.box.seal(result)
}
@@ -205,14 +203,14 @@ public extension CatchMixin where T == Void {
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
*/
@discardableResult
func recover(on: DispatchQueue? = conf.Q.map, _ body: @escaping(Error) -> Void) -> Guarantee<Void> {
func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(Error) -> Void) -> Guarantee<Void> {
let rg = Guarantee<Void>(.pending)
pipe {
switch $0 {
case .fulfilled:
rg.box.seal(())
case .rejected(let error):
on.async {
on.async(flags: flags) {
body(error)
rg.box.seal(())
}
@@ -230,7 +228,7 @@ public extension CatchMixin where T == Void {
- Parameter body: The handler to execute if this promise is rejected.
- SeeAlso: [Cancellation](http://promisekit.org/docs/)
*/
func recover(on: DispatchQueue? = conf.Q.map, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> Void) -> Promise<Void> {
func recover(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, policy: CatchPolicy = conf.catchPolicy, _ body: @escaping(Error) throws -> Void) -> Promise<Void> {
let rg = Promise<Void>(.pending)
pipe {
switch $0 {
@@ -238,7 +236,7 @@ public extension CatchMixin where T == Void {
rg.box.seal(.fulfilled(()))
case .rejected(let error):
if policy == .allErrors || !error.isCancelled {
on.async {
on.async(flags: flags) {
do {
rg.box.seal(.fulfilled(try body(error)))
} catch {

View File

@@ -66,10 +66,10 @@ public class Guarantee<T>: Thenable {
public extension Guarantee {
@discardableResult
func done(on: DispatchQueue? = conf.Q.return, _ body: @escaping(T) -> Void) -> Guarantee<Void> {
func done(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> Void) -> Guarantee<Void> {
let rg = Guarantee<Void>(.pending)
pipe { (value: T) in
on.async {
on.async(flags: flags) {
body(value)
rg.box.seal(())
}
@@ -77,10 +77,10 @@ public extension Guarantee {
return rg
}
func map<U>(on: DispatchQueue? = conf.Q.map, _ body: @escaping(T) -> U) -> Guarantee<U> {
func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> U) -> Guarantee<U> {
let rg = Guarantee<U>(.pending)
pipe { value in
on.async {
on.async(flags: flags) {
rg.box.seal(body(value))
}
}
@@ -88,10 +88,10 @@ public extension Guarantee {
}
@discardableResult
func then<U>(on: DispatchQueue? = conf.Q.map, _ body: @escaping(T) -> Guarantee<U>) -> Guarantee<U> {
func then<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) -> Guarantee<U>) -> Guarantee<U> {
let rg = Guarantee<U>(.pending)
pipe { value in
on.async {
on.async(flags: flags) {
body(value).pipe(to: rg.box.seal)
}
}
@@ -125,6 +125,29 @@ public extension Guarantee {
}
}
public extension Guarantee where T: Sequence {
/**
`Guarantee<[T]>` => `T` -> `Guarantee<U>` => `Guaranetee<[U]>`
firstly {
.value([1,2,3])
}.thenMap {
.value($0 * 2)
}.done {
// $0 => [2,4,6]
}
*/
func thenMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) -> Guarantee<U>) -> Guarantee<[U]> {
return then(on: on, flags: flags) {
when(fulfilled: $0.map(transform))
}.recover {
// if happens then is bug inside PromiseKit
fatalError(String(describing: $0))
}
}
}
#if swift(>=3.1)
public extension Guarantee where T == Void {
convenience init() {

View File

@@ -30,12 +30,12 @@ public extension Thenable {
//
}
*/
func then<U: Thenable>(on: DispatchQueue? = conf.Q.map, file: StaticString = #file, line: UInt = #line, _ body: @escaping(T) throws -> U) -> Promise<U.T> {
func then<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) throws -> U) -> Promise<U.T> {
let rp = Promise<U.T>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
on.async {
on.async(flags: flags) {
do {
let rv = try body(value)
guard rv !== rp else { throw PMKError.returnedSelf }
@@ -68,12 +68,12 @@ public extension Thenable {
//
}
*/
func map<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T) throws -> U) -> Promise<U> {
func map<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U) -> Promise<U> {
let rp = Promise<U>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
on.async {
on.async(flags: flags) {
do {
rp.box.seal(.fulfilled(try transform(value)))
} catch {
@@ -102,12 +102,12 @@ public extension Thenable {
// either `PMKError.compactMap` or a `JSONError`
}
*/
func compactMap<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T) throws -> U?) -> Promise<U> {
func compactMap<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T) throws -> U?) -> Promise<U> {
let rp = Promise<U>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
on.async {
on.async(flags: flags) {
do {
if let rv = try transform(value) {
rp.box.seal(.fulfilled(rv))
@@ -141,12 +141,12 @@ public extension Thenable {
print(response.data)
}
*/
func done(on: DispatchQueue? = conf.Q.return, _ body: @escaping(T) throws -> Void) -> Promise<Void> {
func done(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping(T) throws -> Void) -> Promise<Void> {
let rp = Promise<Void>(.pending)
pipe {
switch $0 {
case .fulfilled(let value):
on.async {
on.async(flags: flags) {
do {
try body(value)
rp.box.seal(.fulfilled(()))
@@ -181,8 +181,8 @@ public extension Thenable {
print(foo, " is Void")
}
*/
func get(on: DispatchQueue? = conf.Q.return, _ body: @escaping (T) throws -> Void) -> Promise<T> {
return map(on: on) {
func get(on: DispatchQueue? = conf.Q.return, flags: DispatchWorkItemFlags? = nil, _ body: @escaping (T) throws -> Void) -> Promise<T> {
return map(on: on, flags: flags) {
try body($0)
return $0
}
@@ -264,8 +264,8 @@ public extension Thenable where T: Sequence {
// $0 => [2,4,6]
}
*/
func mapValues<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U]> {
return map(on: on){ try $0.map(transform) }
func mapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U]> {
return map(on: on, flags: flags){ try $0.map(transform) }
}
/**
@@ -279,8 +279,8 @@ public extension Thenable where T: Sequence {
// $0 => [1,1,2,2,3,3]
}
*/
func flatMapValues<U: Sequence>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.Iterator.Element]> {
return map(on: on){ (foo: T) in
func flatMapValues<U: Sequence>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.Iterator.Element]> {
return map(on: on, flags: flags){ (foo: T) in
try foo.flatMap{ try transform($0) }
}
}
@@ -296,8 +296,8 @@ public extension Thenable where T: Sequence {
// $0 => [1,2,3]
}
*/
func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U?) -> Promise<[U]> {
return map(on: on) { foo -> [U] in
func compactMapValues<U>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U?) -> Promise<[U]> {
return map(on: on, flags: flags) { foo -> [U] in
#if !swift(>=3.3) || (swift(>=4) && !swift(>=4.1))
return try foo.flatMap(transform)
#else
@@ -317,8 +317,8 @@ public extension Thenable where T: Sequence {
// $0 => [2,4,6]
}
*/
func thenMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T]> {
return then(on: on) {
func thenMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T]> {
return then(on: on, flags: flags) {
when(fulfilled: try $0.map(transform))
}
}
@@ -334,8 +334,8 @@ public extension Thenable where T: Sequence {
// $0 => [1,1,2,2,3,3]
}
*/
func thenFlatMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T.Iterator.Element]> where U.T: Sequence {
return then(on: on) {
func thenFlatMap<U: Thenable>(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ transform: @escaping(T.Iterator.Element) throws -> U) -> Promise<[U.T.Iterator.Element]> where U.T: Sequence {
return then(on: on, flags: flags) {
when(fulfilled: try $0.map(transform))
}.map(on: nil) {
$0.flatMap{ $0 }
@@ -353,8 +353,8 @@ public extension Thenable where T: Sequence {
// $0 => [2,3]
}
*/
func filterValues(on: DispatchQueue? = conf.Q.map, _ isIncluded: @escaping (T.Iterator.Element) -> Bool) -> Promise<[T.Iterator.Element]> {
return map(on: on) {
func filterValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil, _ isIncluded: @escaping (T.Iterator.Element) -> Bool) -> Promise<[T.Iterator.Element]> {
return map(on: on, flags: flags) {
$0.filter(isIncluded)
}
}
@@ -387,7 +387,7 @@ public extension Thenable where T: Collection {
public extension Thenable where T: Sequence, T.Iterator.Element: Comparable {
/// - Returns: a promise fulfilled with the sorted values of this `Sequence`.
func sortedValues(on: DispatchQueue? = conf.Q.map) -> Promise<[T.Iterator.Element]> {
return map(on: on){ $0.sorted() }
func sortedValues(on: DispatchQueue? = conf.Q.map, flags: DispatchWorkItemFlags? = nil) -> Promise<[T.Iterator.Element]> {
return map(on: on, flags: flags){ $0.sorted() }
}
}