diff --git a/docs/source/fetching-queries.md b/docs/source/fetching-queries.md index 807ec11df6..fda16fb517 100644 --- a/docs/source/fetching-queries.md +++ b/docs/source/fetching-queries.md @@ -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). ## Typed query results @@ -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 @@ -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 diff --git a/docs/source/fragments.md b/docs/source/fragments.md index c437620dda..8ea63e777f 100644 --- a/docs/source/fragments.md +++ b/docs/source/fragments.md @@ -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] @@ -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 } ``` @@ -93,8 +94,8 @@ query HeroAndFriends($episode: Episode) { And results from inline fragments with type conditions will be made available through specially generated `as` 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 } ``` @@ -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 } ``` diff --git a/docs/source/mutations.md b/docs/source/mutations.md index 362f22a523..62389645eb 100644 --- a/docs/source/mutations.md +++ b/docs/source/mutations.md @@ -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) } ``` @@ -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) } ``` diff --git a/docs/source/watching-queries.md b/docs/source/watching-queries.md index 99a8c057d5..93c334d085 100644 --- a/docs/source/watching-queries.md +++ b/docs/source/watching-queries.md @@ -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 } ``` @@ -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) } -}) +} ```