diff --git a/Documentation/Appendix.md b/Documentation/Appendix.md index 6560dce74..d3797f4d9 100644 --- a/Documentation/Appendix.md +++ b/Documentation/Appendix.md @@ -1,6 +1,6 @@ -# Common misusage +# Common Misusage -## Doubling up promises +## Doubling up Promises Don’t do this: @@ -37,7 +37,7 @@ func toggleNetworkSpinnerWithPromise(funcToCall: () -> Promise) -> Promise You already *had* a promise, you don’t need to wrap it in another promise. -## Optionals in promises +## Optionals in Promises When we see `Promise`, it usually implies a misuse of promises. For example: @@ -73,9 +73,9 @@ return firstly { > *Note*: Use `compactMap` when an API outside your control returns an Optional and you want to generate an error instead of propagating `nil`. -# Tips n’ tricks +# Tips n’ Tricks -## Background-loaded member variables +## Background-Loaded Member Variables ```swift class MyViewController: UIViewController { @@ -88,7 +88,7 @@ class MyViewController: UIViewController { } ``` -## Chaining animations +## Chaining Animations ```swift firstly { @@ -108,7 +108,7 @@ firstly { ``` -## Voiding promises +## Voiding Promises It is often convenient to erase the type of a promise to facilitate chaining. For example, `UIView.animate(.promise)` returns `Guarantee` because UIKit’s @@ -145,7 +145,7 @@ You normally don't have to do this explicitly because `when` does it for you for up to 5 parameters. -## Blocking (await) +## Blocking (Await) Sometimes you have to block the main thread to await completion of an asynchronous task. In these cases, you can (with caution) use `wait`: @@ -162,7 +162,7 @@ public extension UNUserNotificationCenter { The task under the promise **must not** call back onto the current thread or it will deadlock. -## Starting a chain on a background queue/thread +## Starting a Chain on a Background Queue/Thread `firstly` deliberately does not take a queue. A detailed rationale for this choice can be found in the ticket tracker. diff --git a/Documentation/CommonPatterns.md b/Documentation/CommonPatterns.md index e9b360be0..44bc4744f 100644 --- a/Documentation/CommonPatterns.md +++ b/Documentation/CommonPatterns.md @@ -1,7 +1,7 @@ -# Common patterns +# Common Patterns One feature of promises that makes them particularly useful is that they are composable. -This fact enables complex, yet safe, asynchronous patterns that would otherwise be quite +This fact enables complex, yet safe asynchronous patterns that would otherwise be quite intimidating when implemented with traditional methods. @@ -32,7 +32,7 @@ apps without fear of the spaghetti code (and associated refactoring pains) of asynchronous systems that use completion handlers. -## APIs that use promises +## APIs That Use Promises Promises are composable, so return them instead of accepting completion blocks: @@ -64,7 +64,7 @@ your app without violating architectural boundaries. > *Note*: We provide [promises for Alamofire](https://github.com/PromiseKit/Alamofire-) too! -## Background work +## Background Work ```swift class MyRestAPI { @@ -92,7 +92,7 @@ a background queue. See `PromiseKit.conf`. Note that we suggest only changing the queue for the `map` suite of functions, so `done` and `catch` will continue to run on the main queue, which is *usually* what you want. -## Failing chains +## Failing Chains If an error occurs mid-chain, simply throw an error: @@ -129,7 +129,7 @@ avoiding throwing an error because you couldn't be bothered to define a good glo `Error` `enum`. -## Abstracting away asychronicity +## Abstracting Away Asychronicity ```swift var fetch = API.fetch() @@ -166,7 +166,7 @@ Above, we see that you can call `then` as many times on a promise as you like. All the blocks will be executed in the order they were added. -## Chaining sequences +## Chaining Sequences When you have a series of tasks to perform on an array of data: @@ -213,7 +213,7 @@ to ensure this is to use `asVoid()`. Note that if any component promise rejects, the `race` will reject, too. -# Minimum duration +# Minimum Duration Sometimes you need a task to take *at least* a certain amount of time. (For example, you want to show a progress spinner, but if it shows for less than 0.3 seconds, the UI @@ -287,7 +287,7 @@ need to cancel the underlying task! > The library [CancellablePromiseKit](https://github.com/johannesd/CancellablePromiseKit) extends the concept of Promises to fully cover cancellable tasks. -## Retry / polling +## Retry / Polling ```swift func attempt(maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise) -> Promise { @@ -315,7 +315,7 @@ In most cases, you should probably supplement the code above so that it re-attem specific error conditions. -## Wrapping delegate systems +## Wrapping Delegate Systems Be careful with Promises and delegate systems, as they are not always compatible. Promises complete *once*, whereas most delegate systems may notify their delegate many @@ -388,7 +388,7 @@ CLLocationManager.requestLocation().recover { error -> Promise in Be careful not to ignore all errors, though! Recover only those errors that make sense to recover. -## Promises for modal view controllers +## Promises for Modal View Controllers ```swift class ViewController: UIViewController { @@ -422,7 +422,7 @@ explicitly. Nothing seems to beat storyboard segues for decoupling an app's controllers. -## Saving previous results +## Saving Previous Results Let’s say you have: @@ -463,7 +463,7 @@ login().then { username in The code above simply maps `Promise` into `Promise<(UIImage, String)>`. -## Waiting on multiple promises, whatever their result +## Waiting on Multiple Promises, Whatever Their Result Use `when(resolved:)`: diff --git a/Documentation/FAQ.md b/Documentation/FAQ.md index 9c6a60fae..f746954ed 100644 --- a/Documentation/FAQ.md +++ b/Documentation/FAQ.md @@ -113,7 +113,7 @@ when(fulfilled: p1, p2).catch { error in No. PromiseKit contains hardly any source code. In fact, it is quite lightweight. Any “weight” relative to other promise implementations derives from 6 years of bug fixes -and tuning, from the fact that we have *stellar* Objective-C-to-Swift bridging, and +and tuning, from the fact that we have *stellar* Objective-C-to-Swift bridging and from important things such as [Zalgo prevention](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) that hobby-project implementations don’t consider. @@ -172,20 +172,20 @@ PromiseKit is a lot simpler. The top-level difference between PromiseKit and RxSwift is that RxSwift `Observable`s (roughly analogous to PromiseKit `Promise`s) do not necessarily return a single result: they may emit -zero, one, or an infinite stream of values. This small conceptual change ramifies into an API +zero, one, or an infinite stream of values. This small conceptual change leads to an API that's both surprisingly powerful and surprisingly complex. -RxSwift requires commitment to a paradigm shift in how you program: it proposes that you +RxSwift requires commitment to a paradigm shift in how you program. It proposes that you restructure your code as a matrix of interacting value pipelines. When applied properly to a suitable problem, RxSwift can yield great benefits in robustness and simplicity. But not all applications are suitable for RxSwift. By contrast, PromiseKit selectively applies the best parts of reactive programming to the hardest part of pure Swift development, the management of asynchrony. It's a broadly -applicable tool: most asynchronous code can be clarified, simplified, and made more robust +applicable tool. Most asynchronous code can be clarified, simplified and made more robust just by converting it to use promises. (And the conversion process is easy.) -Promises make for code that is clear to most developers. RxSwift, perhaps not: take a look at this +Promises make for code that is clear to most developers. RxSwift, perhaps not. Take a look at this [signup panel](https://github.com/ReactiveX/RxSwift/tree/master/RxExample/RxExample/Examples/GitHubSignup) implemented in RxSwift and see what you think. (Note that this is one of RxSwift's own examples.) @@ -199,18 +199,18 @@ So, RxSwift tries hard to supply every operator you might ever want to use right hundreds. PromiseKit supplies a few utilities to help with specific scenarios, but because it's trivial to write your own chain elements, there's no need for all this extra code in the library. -* PromiseKit dispatches the execution of every block. RxSwift might or might not. Moreover, the +* PromiseKit dispatches the execution of every block. RxSwift dispatches only when told to do so. Moreover, the current dispatching state is an attribute of the chain, not the specific block, as it is in PromiseKit. -The RxSwift system is more powerful but more complex. PromiseKit is simple, predictable, and safe. +The RxSwift system is more powerful but more complex. PromiseKit is simple, predictable and safe. * In PromiseKit, both sides of a branched chain refer back to their shared common ancestors. In RxSwift, -branching normally creates a duplicate parallel chain that reruns the code at the head of the chain. -Except when it doesn't. The rules for determining what will actually happen are complex, and given +branching normally creates a duplicate parallel chain that reruns the code at the head of the chain...except +when it doesn't. The rules for determining what will actually happen are complex, and given a chain created by another chunk of code, you can't really tell what the behavior will be. * Because RxSwift chains don't necessarily terminate on their own, RxSwift needs you to take on some explicit garbage collection duties to ensure that pipelines that are no longer needed are properly -deallocated. All promises yield a single value, terminate, and then automatically deallocate themselves. +deallocated. All promises yield a single value, terminate and then automatically deallocate themselves. You can find some additional discussion in [this ticket](https://github.com/mxcl/PromiseKit/issues/484). diff --git a/Documentation/GettingStarted.md b/Documentation/GettingStarted.md index 64081370c..280341a59 100644 --- a/Documentation/GettingStarted.md +++ b/Documentation/GettingStarted.md @@ -227,12 +227,12 @@ firstly { } ``` -`when` takes promises, waits for them to resolve, and returns a promise containing the results. +`when` takes promises, waits for them to resolve and returns a promise containing the results. As with any promise chain, if any of the component promises fail, the chain calls the next `catch`. -# PromiseKit extensions +# PromiseKit Extensions When we made PromiseKit, we understood that we wanted to use *only* promises to implement asynchronous behavior. So wherever possible, we offer extensions to Apple’s APIs that reframe @@ -263,7 +263,7 @@ has been copiously documented. > We also provide extensions for common libraries such as [Alamofire](https://github.com/PromiseKit/Alamofire-). -# Making promises +# Making Promises The standard extensions will take you a long way, but sometimes you'll still need to start chains of your own. Maybe you're using a third party API that doesn’t provide promises, or perhaps you wrote @@ -356,7 +356,7 @@ to return an `Optional`. If you return `nil`, the chain fails with painful. We hoped the pain would disappear with new Swift versions. However, it has become clear that the various pain points are here to stay. In fact, we as library authors are expected to disambiguate at the naming level of our API. -Therefore, we have split the three main kinds of `then` into `then`, `map`, and +Therefore, we have split the three main kinds of `then` into `then`, `map` and `done`. After using these new functions, we realized this is much nicer in practice, so we added `compactMap` as well (modeled on `Optional.compactMap`). @@ -440,7 +440,7 @@ login().then { creds in Here is a key understanding: `login()` returns a `Promise`, and all `Promise`s have a `then` function. `firstly` returns a `Promise`, and `then` returns a `Promise`, too! But don’t worry too much about these details. Learn the *patterns* to start with. Then, when you are ready to advance, learn the underlying architecture. -## `when` variants +## `when` Variants `when` is one of PromiseKit’s more useful functions, and so we offer several variants. @@ -458,7 +458,7 @@ for this limitation. advanced patterns guide for typical usage. -## Swift closure inference +## Swift Closure Inference Swift automatically infers returns and return types for one-line closures. The following two forms are the same: @@ -486,7 +486,7 @@ pain points in using PromiseKit and Swift. -# Further reading +# Further Reading The above information is the 90% you will use. We **strongly** suggest reading the [API Reference]. diff --git a/Documentation/Installation.md b/Documentation/Installation.md index d0afa2bbb..f3e038374 100644 --- a/Documentation/Installation.md +++ b/Documentation/Installation.md @@ -101,7 +101,7 @@ github "mxcl/PromiseKit" ~> 3.5 [swift-2.0-minimal-changes]: https://github.com/mxcl/PromiseKit/tree/swift-2.0-minimal-changes -# Using Git submodules for PromiseKit’s extensions +# Using Git Submodules for PromiseKit’s Extensions > *Note*: This is a more advanced technique. diff --git a/Documentation/ObjectiveC.md b/Documentation/ObjectiveC.md index 2515915e4..bbc8aa165 100644 --- a/Documentation/ObjectiveC.md +++ b/Documentation/ObjectiveC.md @@ -124,7 +124,7 @@ myPromise.catch(^{ Another important distinction is that the `value` property returns even if the promise is rejected; in that case, it returns the `NSError` object with which the promise was rejected. -# Bridging between Objective-C & Swift +# Bridging Between Objective-C & Swift Let’s say you have: diff --git a/README.md b/README.md index f97e04904..6d1748be0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ --- Promises simplify asynchronous programming, freeing you up to focus on the more -important things. They are easy to learn, easy to master, and result in clearer, +important things. They are easy to learn, easy to master and result in clearer, more readable code. Your co-workers will thank you. ```swift @@ -28,7 +28,7 @@ firstly { PromiseKit is a thoughtful and complete implementation of promises for any platform that has a `swiftc`. It has *excellent* Objective-C bridging and -*delightful* specializations for iOS, macOS, tvOS, and watchOS. It is a top-100 +*delightful* specializations for iOS, macOS, tvOS and watchOS. It is a top-100 pod used in many of the most popular apps in the world. [![codecov](https://codecov.io/gh/mxcl/PromiseKit/branch/master/graph/badge.svg)](https://codecov.io/gh/mxcl/PromiseKit) @@ -49,9 +49,9 @@ target "Change Me!" do end ``` -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)). +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 Xcodes, see our [Installation Guide](Documentation/Installation.md). We @@ -95,7 +95,7 @@ pod "PromiseKit/CorePromise", "~> 6.0" > *Note:* Carthage installations come with no extensions by default. -## Choose your networking library +## Choose Your Networking Library Promise chains commonly start with a network operation. Thus, we offer extensions for `URLSession`: