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
34 changes: 26 additions & 8 deletions docs/source/fetching-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,34 @@ query HeroName($episode: Episode) {
Apollo iOS will generate a `HeroNameQuery` class that you can construct (with variables) and pass to `ApolloClient#fetch(query:)`:

```swift
apollo.fetch(query: HeroNameQuery(episode: .empire)) { (result, error) in
print(result?.data?.hero?.name) // Luke Skywalker
apollo.fetch(query: HeroNameQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
print(data.hero?.name) // Luke Skywalker
}
```

> By default, Apollo will deliver query results on the main thread, which is probably what you want if you're using them to update the UI. `fetch(query:)` takes an optional `queue:` parameter however, if you want your result handler to be called on a background queue.

The `error` parameter to the completion handler signals network or response format errors (such as invalid JSON).
To handle potential errors, check the `failure(Failure)` result case, which details network or response format errors (such as invalid JSON):

```swift
apollo.fetch(query: HeroNameQuery(episode: .empire)) { result in
switch result {
case .success(let graphQLResult):
if let name = graphQLResult.data?.hero?.name {
print(name) // Luke Skywalker
} else if let errors = graphQLResult.errors {
// GraphQL errors
print(errors)
}
case .failure(let error):
// Network or response format errors
print(error)
}
}
```

In addition to an optional `data` property, `result` contains an optional `errors` array with GraphQL errors (for more on this, see the sections on [error handling](https://facebook.github.io/graphql/#sec-Error-handling) and the [response format](https://facebook.github.io/graphql/#sec-Response-Format) in the GraphQL specification).
In addition to an optional `data` property, `success(Success)` result case contains an optional `errors` array with GraphQL errors (for more on this, see the sections on [response format errors](https://graphql.github.io/graphql-spec/June2018/#sec-Errors) in the GraphQL specification).
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link may need to be updated in the future, but the past one redirects to the spec home page which is less useful.


## Typed query results

Expand Down Expand Up @@ -87,8 +105,8 @@ query HeroAndFriendsNames($episode: Episode) {
You can fetch results and access data using the following code:

```swift
apollo.fetch(query: HeroAndFriendsNamesQuery(episode: .empire)) { (result, error) in
guard let data = result?.data else { return }
apollo.fetch(query: HeroAndFriendsNamesQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
print(data.hero?.name) // Luke Skywalker
print(data.hero?.friends?.flatMap { $0?.name }.joined(separator: ", "))
// Prints: Han Solo, Leia Organa, C-3PO, R2-D2
Expand Down Expand Up @@ -126,8 +144,8 @@ The classes generated by Apollo iOS can be converted to JSON using their `jsonOb

For example:
```swift
apollo.fetch(query: HeroAndFriendsNamesQuery(episode: .empire)) { (result, error) in
guard let data = result?.data else { return }
apollo.fetch(query: HeroAndFriendsNamesQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }

// Serialize the response as JSON
let json = data.jsonObject
Expand Down
15 changes: 8 additions & 7 deletions docs/source/fragments.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ This also works the other way around. The parent view controller only has to kno
In fact, this is the main reason fields included through fragments are not exposed directly, but require you to access the data through the fragment explicitly:

```swift
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { (result, error) in
guard let data = result?.data else { return }
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
print(data.hero?.name) // Luke Skywalker
print(data.hero?.appearsIn) // WON'T WORK
print(data.hero?.fragments.heroDetails.appearsIn) // [.newhope, .empire, .jedi]
Expand Down Expand Up @@ -72,7 +72,8 @@ fragment DroidDetails on Droid {
You can access named fragments with type conditions the same way you access other fragments, but their type will be optional to reflect the fact that their fields will only be available if the object type matches:

```swift
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { (result, error) in
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
data.hero?.fragments.droidDetails?.primaryFunction
}
```
Expand All @@ -93,8 +94,8 @@ query HeroAndFriends($episode: Episode) {
And results from inline fragments with type conditions will be made available through specially generated `as<Type>` properties:

```swift
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { (result, error) in
guard let data = result?.data else { return }
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
data.hero?.asDroid?.primaryFunction
}
```
Expand All @@ -121,8 +122,8 @@ fragment HeroDetails on Character {
```

```swift
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { (result, error) in
guard let data = result?.data else { return }
apollo.fetch(query: HeroAndFriendsQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
data.hero?.fragments.heroDetails.asDroid?.primaryFunction
}
```
Expand Down
10 changes: 6 additions & 4 deletions docs/source/mutations.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ The above mutation will upvote a post on the server. The result might be:
Similar to queries, mutations are represented by instances of generated classes, conforming to the `GraphQLMutation` protocol. Constructor arguments are used to define mutation variables. You pass a mutation object to `ApolloClient#perform(mutation:)` to send the mutation to the server, execute it, and receive typed results:

```swift
apollo.perform(mutation: UpvotePostMutation(postId: postId)) { (result, error) in
print(result?.data?.upvotePost?.votes)
apollo.perform(mutation: UpvotePostMutation(postId: postId)) { result in
guard let data = try? result.get().data else { return }
print(data.upvotePost?.votes)
}
```

Expand All @@ -52,8 +53,9 @@ mutation UpvotePost($postId: Int!) {
```

```swift
apollo.perform(mutation: UpvotePostMutation(postId: postId)) { (result, error) in
self.configure(with: result?.data?.upvotePost?.fragments.postDetails)
apollo.perform(mutation: UpvotePostMutation(postId: postId)) { result in
guard let data = try? result.get().data else { return }
self.configure(with: data.upvotePost?.fragments.postDetails)
}
```

Expand Down
11 changes: 6 additions & 5 deletions docs/source/watching-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ As mentioned in the introduction, Apollo iOS does more than simply run your quer
Watching a query is very similar to fetching a query. The main difference is that you don't just receive an initial result, but your result handler will be invoked whenever relevant data in the cache changes:

```swift
let watcher = apollo.watch(query: HeroNameQuery(episode: .empire)) { (result, error) in
print(data?.hero?.name) // Luke Skywalker
let watcher = apollo.watch(query: HeroNameQuery(episode: .empire)) { result in
guard let data = try? result.get().data else { return }
print(data.hero?.name) // Luke Skywalker
}
```

Expand Down Expand Up @@ -58,10 +59,10 @@ store.withinReadWriteTransaction { transaction in
try transaction.update(query: query) { (data: inout HeroNameQuery.Data) in
data.hero?.name = "Artoo"

let result = store.load(query: query).result!.valueOrError()
let graphQLResult = try? store.load(query: query).result?.get()

// Prints "Artoo"
print(result.data?.hero?.name)
print(graphQLResult?.data?.hero?.name)
}
})
}
```