Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions Documentation/Appendix.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Common misusage
# Common Misusage

## Doubling up promises
## Doubling up Promises

Don’t do this:

Expand Down Expand Up @@ -37,7 +37,7 @@ func toggleNetworkSpinnerWithPromise<T>(funcToCall: () -> Promise<T>) -> 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<Item?>`, it usually implies a misuse of promises. For
example:
Expand Down Expand Up @@ -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 {
Expand All @@ -88,7 +88,7 @@ class MyViewController: UIViewController {
}
```

## Chaining animations
## Chaining Animations

```swift
firstly {
Expand All @@ -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<Bool>` because UIKit’s
Expand Down Expand Up @@ -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`:
Expand All @@ -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.
Expand Down
26 changes: 13 additions & 13 deletions Documentation/CommonPatterns.md
Original file line number Diff line number Diff line change
@@ -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.


Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<T>(maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise<T>) -> Promise<T> {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -388,7 +388,7 @@ CLLocationManager.requestLocation().recover { error -> Promise<CLLocation> 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 {
Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -463,7 +463,7 @@ login().then { username in
The code above simply maps `Promise<String>` into `Promise<(UIImage, String)>`.


## Waiting on multiple promises, whatever their result
## Waiting on Multiple Promises, Whatever Their Result

Use `when(resolved:)`:

Expand Down
20 changes: 10 additions & 10 deletions Documentation/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.)

Expand All @@ -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).

Expand Down
14 changes: 7 additions & 7 deletions Documentation/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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`).

Expand Down Expand Up @@ -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.

Expand All @@ -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:
Expand Down Expand Up @@ -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].
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion Documentation/ObjectiveC.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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`:
Expand Down