diff --git a/docs/shared/carthage-installation-panel.mdx b/docs/shared/carthage-installation-panel.mdx index 235e48edcf..dfc6af49a8 100644 --- a/docs/shared/carthage-installation-panel.mdx +++ b/docs/shared/carthage-installation-panel.mdx @@ -1,40 +1,34 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - - + -

Set up your `Cartfile`

+#### Set up your `Cartfile` Add `github "apollographql/apollo-ios"` to your Cartfile.
- + -

Check out and build dependencies

+#### Check out and build dependencies Run `carthage update --use-xcframeworks --platform ios` (or `--platform ios,macos` to build both Mac and iOS). > **Note:** There's an issue with the way Carthage uses Lipo in the Xcode 12 GM. Please `cd` into `[YourProject]/Carthage/Checkouts/apollo-ios/scripts` and then run `./carthage-build-workaround.sh` to resolve this build issue.
- + -

Add built frameworks to your project

+#### Add built frameworks to your project Drag and drop `Apollo.framework` from the appropriate `Carthage/Build/iOS` or `Carthage/Build/Mac` folder to the **Embedded Binaries** section of your application target's **General** settings tab. This should also cause them to appear in the **Linked Frameworks And Libraries** section automatically. - To include the `ApolloSQLite` library, also drag `ApolloSQLite.framework` and `SQLite.framework` to this area. - To include the `ApolloWebSocket` library, also drag `ApolloWebSocket.framework` and `Starscream.framework` to this area.
- + -

Work around Carthage submission bug

+#### Work around Carthage submission bug On your application target's **Build Phases** settings tab, click the **+** icon and choose **New Run Script Phase**. Create a Run Script in which you specify your shell (e.g., `bin/sh`) and add the following contents to the script area below the shell: @@ -53,8 +47,10 @@ Again, if you're adding `ApolloSQLite` or `ApolloWebSocket`, please make sure to This script works around an [App Store submission bug](http://www.openradar.me/radar?id=6409498411401216) triggered by universal binaries and ensures that necessary bitcode-related files and dSYMs are copied when archiving.
- - You're done! + + +You're done! +
diff --git a/docs/shared/carthage-run-script-panel.mdx b/docs/shared/carthage-run-script-panel.mdx index 02ec8b6966..bf592a7c73 100644 --- a/docs/shared/carthage-run-script-panel.mdx +++ b/docs/shared/carthage-run-script-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - The scripts and binaries that you need to generate code are included in the `Carthage/Checkouts` folder. If this folder is not checked into version control, all developers on a team (and your CI machine) need to run `carthage checkout` when changes are made to the version to ensure they have the correct underlying binaries and scripts. diff --git a/docs/shared/pods-installation-panel.mdx b/docs/shared/pods-installation-panel.mdx index 5275dadaee..7dfd4160a3 100644 --- a/docs/shared/pods-installation-panel.mdx +++ b/docs/shared/pods-installation-panel.mdx @@ -1,15 +1,9 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - - + -

Install or update CocoaPods

+#### Install or update CocoaPods Because Apollo iOS uses Swift 5, you need to use CocoaPods version `1.7.0` or later. You can install CocoaPods with the following command: @@ -18,9 +12,9 @@ Because Apollo iOS uses Swift 5, you need to use CocoaPods version `1.7.0` or la ```
- + -

Add dependencies

+#### Add dependencies Add `pod "Apollo"` to your Podfile. @@ -28,18 +22,20 @@ Add `pod "Apollo"` to your Podfile. - To include the `ApolloWebSocket` framework, also add `pod "Apollo/WebSocket"`
- + Run `pod install`. - + Use the `.xcworkspace` file generated by CocoaPods to work on your project. - - You're done! + + +You're done! +
diff --git a/docs/shared/pods-run-script-panel.mdx b/docs/shared/pods-run-script-panel.mdx index 9ac0edf6ac..96225966fd 100644 --- a/docs/shared/pods-run-script-panel.mdx +++ b/docs/shared/pods-run-script-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - Our CocoaPods install includes the code-generation scripts and binaries of the `apollo` CLI client as files which will not be added to the framework, but which you can still call from a Run Script Build Phase. Add the following to the Run Script: diff --git a/docs/shared/spm-installation-panel.mdx b/docs/shared/spm-installation-panel.mdx index 1b1772bc41..0d84f6eea5 100644 --- a/docs/shared/spm-installation-panel.mdx +++ b/docs/shared/spm-installation-panel.mdx @@ -1,36 +1,30 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - > **Note:** These instructions use the Xcode 13 UI. Xcode 11 is the first version of Xcode that integrates Swift Package manager, whereas older versions require using the command line. If you're using an older version of Xcode, we recommend using CocoaPods instead. - + Go to **File > Add Packages...** Adding an SPM package - + In the dialog that appears, paste the URL of the Apollo iOS GitHub repo (`https://github.com/apollographql/apollo-ios.git`) into the search bar, then select the `apollo-ios` package that appears: Pasting the Apollo iOS GitHub URL - + Select which version you want to use ([see version history](https://github.com/apollographql/apollo-ios/releases)), then click **Add Package**. Note that Xcode might not automatically select the latest version number! > Xcode automatically suggests the dependency rule `Up to Next Major`. We **strongly** suggest that until the release of Apollo iOS `1.x`, you select `Up To Next Minor` instead, because we might release breaking changes in a minor version. - + Select which packages you want to use. If you're getting started, we recommend selecting just the main `Apollo` library for now. You can always add other packages later if you need them. @@ -41,8 +35,10 @@ Select which packages you want to use. If you're getting started, we recommend s Then, click **Add Package**. - - You're done! + + +You're done! + diff --git a/docs/shared/spm-run-script-panel.mdx b/docs/shared/spm-run-script-panel.mdx index 944e71d8c5..f57fb75e38 100644 --- a/docs/shared/spm-run-script-panel.mdx +++ b/docs/shared/spm-run-script-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - > **Note:** If your Derived Data is in a custom location, go back and use the [Swift Scripting](./swift-scripting) method instead. This script relies on Derived Data being in the default location. Swift Scripting doesn't rely on Derived Data at all. diff --git a/docs/shared/sqlite-carthage-panel.mdx b/docs/shared/sqlite-carthage-panel.mdx index 16eb1e272a..fffde233e1 100644 --- a/docs/shared/sqlite-carthage-panel.mdx +++ b/docs/shared/sqlite-carthage-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - You will need to add the `ApolloSQLite` framework to your target. This should be one of the libraries that gets built automatically on checkout, and should include the dependent libraries necessary to run it. diff --git a/docs/shared/sqlite-cocoapods-panel.mdx b/docs/shared/sqlite-cocoapods-panel.mdx index 37a8eade5a..8669eee26d 100644 --- a/docs/shared/sqlite-cocoapods-panel.mdx +++ b/docs/shared/sqlite-cocoapods-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - Add the following to your `Podfile`: diff --git a/docs/shared/sqlite-spm-panel.mdx b/docs/shared/sqlite-spm-panel.mdx index ef9b20621a..8ff04d0532 100644 --- a/docs/shared/sqlite-spm-panel.mdx +++ b/docs/shared/sqlite-spm-panel.mdx @@ -1,9 +1,3 @@ -import { - ExpansionPanel, - ExpansionPanelList, - ExpansionPanelListItem -} from 'gatsby-theme-apollo-docs'; - Add the following to your `Package.swift`: diff --git a/docs/static/_redirects b/docs/source/_redirects similarity index 60% rename from docs/static/_redirects rename to docs/source/_redirects index e45c57a1f6..77fb1c308a 100644 --- a/docs/static/_redirects +++ b/docs/source/_redirects @@ -1,3 +1,2 @@ /tutorial /docs/ios/tutorial/tutorial-introduction /tutorial/tutorial-create-project /docs/ios/tutorial/tutorial-add-sdk -/docs/ios/tutorial/tutorial-create-project /docs/ios/tutorial/tutorial-add-sdk \ No newline at end of file diff --git a/docs/source/api-reference.md b/docs/source/api-reference.md index 1a6678e593..d18ba8859f 100644 --- a/docs/source/api-reference.md +++ b/docs/source/api-reference.md @@ -1,14 +1,13 @@ --- title: API Reference -description: '' --- -* [Apollo.framework](../api/Apollo/README/) -* [ApolloAPI.framework](../api/ApolloAPI/README/) -* [ApolloUtils.framework](../api/ApolloUtils/README/) -* [ApolloCodegenLib.framework](../api/ApolloCodegenLib/README/) -* [ApolloSQLite.framework](../api/ApolloSQLite/README/) -* [ApolloWebSocket.framework](../api/ApolloWebSocket/README/) +* [Apollo.framework](./api/Apollo/README/) +* [ApolloAPI.framework](./api/ApolloAPI/README/) +* [ApolloUtils.framework](./api/ApolloUtils/README/) +* [ApolloCodegenLib.framework](./api/ApolloCodegenLib/README/) +* [ApolloSQLite.framework](./api/ApolloSQLite/README/) +* [ApolloWebSocket.framework](./api/ApolloWebSocket/README/) Our API reference is automatically generated directly from the inline comments in our code, so if you're adding something new, all you have to do is actually add doc comments and they'll show up here. diff --git a/docs/source/caching.mdx b/docs/source/caching.mdx index 6393cea96b..b2f64c9bac 100644 --- a/docs/source/caching.mdx +++ b/docs/source/caching.mdx @@ -29,7 +29,7 @@ This type of cache is used by default when setting up an `ApolloClient`. If you If for some reason you find you need to instantiate the in-memory cache yourself, you can do so with one line: -```swift:title=Cache%20Setup +```swift title="Cache Setup" import Apollo let cache = InMemoryNormalizedCache() @@ -52,7 +52,7 @@ Once added, you can do the following: 3. Use that SQLite cache to instantiate an `ApolloStore`. 4. Pass that `ApolloStore` into the initializer of `ApolloClient`: -```swift:title=Client%20Setup +```swift title="Client Setup" import Apollo // NOTE: You need this import line if you are **NOT** using CocoaPods. In CocoaPods, diff --git a/docs/source/config.json b/docs/source/config.json new file mode 100644 index 0000000000..ff6f69e89e --- /dev/null +++ b/docs/source/config.json @@ -0,0 +1,35 @@ +{ + "title": "Client (iOS)", + "version": "0.X", + "algoliaFilters": [ + "docset:ios" + ], + "sidebar": { + "Introduction": "/", + "Installation": "/installation", + "API Reference": "/api-reference", + "Tutorial": { + "0. Introduction": "/tutorial/tutorial-introduction", + "1. Add the Apollo SDK": "/tutorial/tutorial-add-sdk", + "2. Obtain your GraphQL schema": "/tutorial/tutorial-obtain-schema", + "3. Execute your first query": "/tutorial/tutorial-execute-query", + "4. Connect your queries to your UI": "/tutorial/tutorial-query-ui", + "5. Paginate results": "/tutorial/tutorial-pagination", + "6. Complete the detail view": "/tutorial/tutorial-detail-view", + "7. Enable authentication": "/tutorial/tutorial-authentication", + "8. Define additional mutations": "/tutorial/tutorial-mutations", + "9. Write your first subscription": "/tutorial/tutorial-subscriptions" + }, + "Usage": { + "Downloading a schema": "/downloading-schema", + "Creating a client": "/initialization", + "Fetching queries": "/fetching-queries", + "Performing mutations": "/mutations", + "Using fragments": "/fragments", + "Client-side caching": "/caching", + "Subscriptions": "/subscriptions", + "Swift scripting": "/swift-scripting", + "Request pipeline (advanced)": "/request-pipeline" + } + } +} \ No newline at end of file diff --git a/docs/source/downloading-schema.md b/docs/source/downloading-schema.md index a666c98d5e..54b8aacc43 100644 --- a/docs/source/downloading-schema.md +++ b/docs/source/downloading-schema.md @@ -14,7 +14,7 @@ You can use the [Apollo CLI](https://www.apollographql.com/docs/devtools/cli/) t apollo schema:download --endpoint=http://localhost:8080/graphql schema.json ``` -Note that if you're using the local version set up for codegen, you should use the same method you're using in the [Add a code generation build step](/installation/#5-add-a-code-generation-build-step) instructions to access that specific CLI. For example, if you're using CocoaPods, you can set it up like this to download your schema: +Note that if you're using the local version set up for codegen, you should use the same method you're using in the [Add a code generation build step](./installation/#5-add-a-code-generation-build-step) instructions to access that specific CLI. For example, if you're using CocoaPods, you can set it up like this to download your schema: ```bash SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts" diff --git a/docs/source/fetching-queries.md b/docs/source/fetching-queries.md index c12cb47062..41cf8fd25b 100644 --- a/docs/source/fetching-queries.md +++ b/docs/source/fetching-queries.md @@ -156,7 +156,7 @@ Again, make sure to define this in a file that is outside of your generated code ## Specifying a cache policy -[This section has moved to the Caching documentation](/caching/). +[This section has moved to the Caching documentation](./caching/). ## Using `GET` instead of `POST` for queries diff --git a/docs/source/index.mdx b/docs/source/index.mdx index 8a6684324a..a6183ad3f6 100644 --- a/docs/source/index.mdx +++ b/docs/source/index.mdx @@ -4,22 +4,22 @@ sidebar_title: Introduction description: A strongly-typed, caching GraphQL client for iOS, written in Swift --- -import { Button } from '@apollo/space-kit/Button'; import { Link } from 'gatsby'; -import { colors } from 'gatsby-theme-apollo-core'; **Apollo iOS** is an [open-source](https://github.com/apollographql/apollo-ios) GraphQL client for native iOS apps, written in Swift. It enables you to execute queries and mutations against a GraphQL server and returns results as operation-specific Swift types.

@@ -43,6 +43,6 @@ Apollo iOS normalizes operation results to build a client-side cache of your dat ## Related libraries -[Apollo Kotlin](https://www.apollographql.com/docs/kotlin/) is a GraphQL client for native Android apps written in Java and Kotlin. It offers Kotlin Multi-Platform integration as well. +[Apollo Kotlin](/kotlin/) is a GraphQL client for native Android apps written in Java and Kotlin. It offers Kotlin Multi-Platform integration as well. -Apollo Client for JavaScript's [React integration](https://apollographql.com/docs/react) works with [React Native](https://facebook.github.io/react-native/) on both iOS and Android. +Apollo Client for JavaScript's [React integration](/react) works with [React Native](https://facebook.github.io/react-native/) on both iOS and Android. diff --git a/docs/source/initialization.mdx b/docs/source/initialization.mdx index b6d35d7ff6..8dc997e9e8 100644 --- a/docs/source/initialization.mdx +++ b/docs/source/initialization.mdx @@ -40,5 +40,5 @@ Apollo iOS provides the following classes that conform to the [`NetworkTransport | `WebSocketTransport` | Transmits _all_ GraphQL operations via WebSocket. Requires the `Apollo/WebSocket` sub-spec. | | `SplitNetworkTransport` | Transmits subscription operations via WebSocket and other operations via HTTP. Requires the `Apollo/WebSocket` sub-spec. | -> * For more information on `RequestChainNetworkTransport`, see [Request pipeline in Apollo iOS](/request-pipeline/). -> * For more information on `WebSocketTransport` and `SplitNetworkTransport`, see [Subscriptions](/subscriptions/). +> * For more information on `RequestChainNetworkTransport`, see [Request pipeline in Apollo iOS](./request-pipeline/). +> * For more information on `WebSocketTransport` and `SplitNetworkTransport`, see [Subscriptions](./subscriptions/). diff --git a/docs/source/installation.mdx b/docs/source/installation.mdx index b948d66b92..9f4f3d9532 100644 --- a/docs/source/installation.mdx +++ b/docs/source/installation.mdx @@ -31,7 +31,7 @@ You can install `Apollo.framework` into your project using any of the three majo ## 3. Add a schema file to your target directory -For Apollo iOS to generate models for your GraphQL operations, you need a local copy of your GraphQL server's schema. To acquire this schema, see [Downloading a schema](/downloading-schema/). +For Apollo iOS to generate models for your GraphQL operations, you need a local copy of your GraphQL server's schema. To acquire this schema, see [Downloading a schema](./downloading-schema/). Make sure to add your `schema.json`/`schema.graphqls` file to the folder where most of your code is, _not_ to the folder where your `.xcodeproj` and/or `.xcworkspace` files are located. @@ -115,7 +115,7 @@ Drag the generated `API.swift` file to your target. Make sure to uncheck the "Copy Files If Needed" checkbox, because it should already be in your project's folder system. Then, make sure you've checked all the Targets the API file needs to be included in. -**Installation complete!** You can now start executing GraphQL operations in your app. To learn how, next check out [Creating a client](/initialization/) and [Fetching queries](/fetching-queries/). +**Installation complete!** You can now start executing GraphQL operations in your app. To learn how, next check out [Creating a client](./initialization/) and [Fetching queries](./fetching-queries/). You can also continue reading below for some [advanced codegen tips](#advanced-codegen-tips-and-tricks). diff --git a/docs/source/request-pipeline.mdx b/docs/source/request-pipeline.mdx index 53cddd8da4..27f999bb22 100644 --- a/docs/source/request-pipeline.mdx +++ b/docs/source/request-pipeline.mdx @@ -1,13 +1,10 @@ --- title: Request pipeline in Apollo iOS -sidebar_title: Request pipeline (advanced) --- -import {ExpansionPanel} from 'gatsby-theme-apollo-docs'; - In Apollo iOS, most `ApolloClient` instances use the `RequestChainNetworkTransport` to execute GraphQL queries and mutations on a remote server. Appropriately, this network transport uses a structure called a **request chain** to process each operation in individual steps. -> For more information on the _subscription_ request pipeline, see [Subscriptions](/subscriptions/). +> For more information on the _subscription_ request pipeline, see [Subscriptions](./subscriptions/). ## Request chains @@ -465,7 +462,7 @@ struct NetworkInterceptorProvider: InterceptorProvider { ### Example `Network` singleton -As when initializing a [basic client](/initialization/#basic-client-creation), it's recommended to create a `Network` singleton to use a single `ApolloClient` instance across your app. +As when initializing a [basic client](./initialization/#basic-client-creation), it's recommended to create a `Network` singleton to use a single `ApolloClient` instance across your app. Here's what that singleton might look like for an advanced client: diff --git a/docs/source/swift-scripting.md b/docs/source/swift-scripting.md index 306c3155d8..499c852f28 100644 --- a/docs/source/swift-scripting.md +++ b/docs/source/swift-scripting.md @@ -1,6 +1,5 @@ --- title: Swift scripting -sidebar_title: Swift scripting --- Apollo Client for iOS enables you to use Swift scripting to perform certain operations that otherwise require the command line. @@ -47,7 +46,7 @@ When you unzip the downloaded repo, you'll see that there's a folder called **`A If you're using the default target structure for an Xcode project, your project's file structure will look essentially like this in Finder: -```txt:title=Sample%20Project%20Structure +```txt title="Sample Project Structure" MyProject // Source root ├─ MyProject.xcodeproj ├─ MyProject/ // Contains app target source files @@ -57,7 +56,7 @@ MyProject // Source root Drag the `ApolloCodegen` folder in **at the same level as your other targets** (in Finder, not in Xcode): -```txt:title=Sample%20Project%20Structure +```txt title="Sample Project Structure" MyProject // Source root ├─ MyProject.xcodeproj ├─ MyProject/ // Contains app target source files @@ -70,7 +69,7 @@ Double-click `Package.swift` in the `ApolloCodegen` folder to open the executabl **Important!** Since a particular version of code generation is tied to a particular version of the SDK, you need to make sure that the `dependencies` section of `Package.swift` is set to grab the same version of the `apollo-ios` library you're using in your main application: -```swift:title=Package.swift +```swift title="Package.swift" .package(name: "Apollo", url: "https://github.com/apollographql/apollo-ios.git", .upToNextMinor(from: "0.49.0")) @@ -139,7 +138,7 @@ swift run ApolloCodegen downloadSchema If you're using the template code and following the sample project structure, the schema should download here: -```txt:title=Sample%20Project%20Structure +```txt title="Sample Project Structure" MyProject // SourceRoot ├─ MyProject.xcodeproj ├─ MyProject/ // Contains app target source files @@ -157,7 +156,7 @@ If you're not familiar with creating an operation in graphQL, please check out t Make sure you've added the operation file to the project files, ideally at or above the level of the `schema.graphqls` (Otherwise, you'll need to manually pass the URL of your operation file to your code generation step): -```txt:title=Sample%20Project%20Structure +```txt title="Sample Project Structure" MyProject // SourceRoot ├─ MyProject.xcodeproj ├─ MyProject/ // Contains app target source files diff --git a/docs/source/tutorial/tutorial-authentication.md b/docs/source/tutorial/tutorial-authentication.md index b7e39747eb..6a9d7b5512 100644 --- a/docs/source/tutorial/tutorial-authentication.md +++ b/docs/source/tutorial/tutorial-authentication.md @@ -62,7 +62,7 @@ Now it's time to actually log the user in, using `LoginViewController.swift`. Yo Still in `submitTapped`, replace the `TODO` with a call to perform the login mutation: -```swift:title=LoginViewController.swift +```swift title="LoginViewController.swift" Network.shared.apollo.perform(mutation: LoginMutation(loginEmail: email)) { [weak self] result in defer { // Re-enable the submit button when this scope exits @@ -95,7 +95,7 @@ Next, you need to store the login credential that's returned by the server. Logi At the top of `LoginViewController.swift`, import the `KeychainSwift` library: -```swift:title=LoginViewController.swift +```swift title="LoginViewController.swift" import KeychainSwift ``` @@ -103,7 +103,7 @@ Next, note that there's a `static let` at the top of the view controller that wi Replace the `TODO` after unwrapping the token with the following: -```swift:title=LoginViewController.swift +```swift title="LoginViewController.swift" let keychain = KeychainSwift() keychain.set(token, forKey: LoginViewController.loginKeychainKey) self?.dismiss(animated: true) @@ -117,13 +117,13 @@ Now, it's time to show the login view controller whenever someone attempts to bo At the top of `DetailViewController.swift`, import the `KeychainSwift` library: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" import KeychainSwift ``` Then, find the `isLoggedIn` method and replace its contents with the following: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private func isLoggedIn() -> Bool { let keychain = KeychainSwift() return keychain.get(LoginViewController.loginKeychainKey) != nil @@ -134,7 +134,7 @@ This code checks if there is any value stored in the keychain under the login ke Find the `bookOrCancelTapped` method and start by determining what to do if the user is logged in or not: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" @IBAction private func bookOrCancelTapped() { guard self.isLoggedIn() else { self.performSegue(withIdentifier: "showLogin", sender: self) @@ -147,7 +147,7 @@ Find the `bookOrCancelTapped` method and start by determining what to do if the Then, replace the `TODO` in the above code with logic to figure out whether a trip on the current launched needs to be booked or cancelled: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" guard let launch = self.launch else { // We don't have enough information yet to know // if we're booking or cancelling, bail. diff --git a/docs/source/tutorial/tutorial-detail-view.md b/docs/source/tutorial/tutorial-detail-view.md index 2c46651caa..6f0a86f07b 100644 --- a/docs/source/tutorial/tutorial-detail-view.md +++ b/docs/source/tutorial/tutorial-detail-view.md @@ -107,13 +107,13 @@ Now that you've confirmed it worked, copy the query (either by selecting all the Now that you know what you're planning to ask for, it's time to set up the UI for the detail screen. Go to `DetailViewController.swift`. First, add a place to hang on to the result of the query. Add the following property to the top of the class: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private var launch: LaunchDetailsQuery.Data.Launch? ``` Next, update the `viewDidLoad` function to clear out anything from the storyboard before attempting to configure the view: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" override func viewDidLoad() { super.viewDidLoad() @@ -126,7 +126,7 @@ override func viewDidLoad() { Delete the existing contents of `configureView()`. In their place, start by adding a check that we have something to display, and a place to display it: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" guard self.missionNameLabel != nil, let launch = self.launch else { @@ -138,7 +138,7 @@ Next, it's time to display all the information you've gotten from your GraphQL s Add the following code below the `guard` statement you just added: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" self.missionNameLabel.text = launch.mission?.name self.title = launch.mission?.name @@ -176,7 +176,7 @@ if launch.isBooked { Then, find the `loadLaunchDetails()` method. Replace the `TODO` with the following, which loads the details using the `LaunchDetailsQuery` you created earlier: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private func loadLaunchDetails() { guard let launchID = self.launchID, @@ -213,7 +213,7 @@ private func loadLaunchDetails() { Finally, update the `didSet` for `launchID` to load the launch details if we don't already have them: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" var launchID: GraphQLID? { didSet { self.loadLaunchDetails() @@ -223,7 +223,7 @@ var launchID: GraphQLID? { and add a `didSet` on the `launch` property to load the UI once the launch is actually loaded. -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private var launch: LaunchDetailsQuery.Data.Launch? { didSet { self.configureView() diff --git a/docs/source/tutorial/tutorial-execute-query.md b/docs/source/tutorial/tutorial-execute-query.md index 74da07a5ae..d4c4887269 100644 --- a/docs/source/tutorial/tutorial-execute-query.md +++ b/docs/source/tutorial/tutorial-execute-query.md @@ -125,13 +125,13 @@ Now that you've generated code and had a chance to see what's in there, it's tim To use the generated operations in `API.swift`, you first create an instance of `ApolloClient`. This instance takes your generated code and uses it to make network calls to your server. It's recommended that this instance is a singleton or static instance that's accessible from anywhere in your codebase. -1. Create a new Swift file called `Network.swift` and copy the code from [Basic client creation](/initialization/#basic-client-creation) into it. Make sure to add `import Apollo` to the top of the file. +1. Create a new Swift file called `Network.swift` and copy the code from [Basic client creation](../initialization/#basic-client-creation) into it. Make sure to add `import Apollo` to the top of the file. 2. Update the URL string to be `https://apollo-fullstack-tutorial.herokuapp.com/graphql` instead of the `localhost` URL in the example. 3. To make sure your `ApolloClient` instance is communicating correctly with the server, add the following code to `AppDelegate.swift` in the `application:didFinishLaunchingWithOptions` method, above `return true`: - ```swift:title=AppDelegate.swift + ```swift title="AppDelegate.swift" Network.shared.apollo.fetch(query: LaunchListQuery()) { result in switch result { case .success(let graphQLResult): diff --git a/docs/source/tutorial/tutorial-mutations.md b/docs/source/tutorial/tutorial-mutations.md index a30466b055..6fd5fd9f81 100644 --- a/docs/source/tutorial/tutorial-mutations.md +++ b/docs/source/tutorial/tutorial-mutations.md @@ -18,7 +18,7 @@ The nice thing is that you can also add your own interceptors to the chain anywh First, create the new interceptor. Go to **File > New > File...** and create a new **Swift File**. Name it **TokenAddingInterceptor.swift**, and make sure it's added to the **RocketReserver** target. Open that file, and add the following code: -```swift:title=TokenAddingInterceptor.swift +```swift title="TokenAddingInterceptor.swift" import Foundation import Apollo @@ -36,13 +36,13 @@ class TokenAddingInterceptor: ApolloInterceptor { Next, import `KeychainSwift` at the top of the file so you can access the key you stored in the keychain in the last step of the tutorial: -```swift:title=TokenAddingInterceptor.swift +```swift title="TokenAddingInterceptor.swift" import KeychainSwift ``` Then, replace the `TODO` within the `interceptAsync` method with code to get the token from the keychain, and add it to your headers if it exists: -```swift:title=TokenAddingInterceptor.swift +```swift title="TokenAddingInterceptor.swift" let keychain = KeychainSwift() if let token = keychain.get(LoginViewController.loginKeychainKey) { request.addHeader(name: "Authorization", value: token) @@ -59,7 +59,7 @@ You can also make your own object conforming to `InterceptorProvider` - or, in t Go to **File > New > File...** and create a new **Swift File**. Name it **NetworkInterceptorProvider.swift**, and make sure it's added to the **RocketReserver** target. Add code which inserts your `TokenAddingInterceptor` before the other interceptors provided by the `DefaultInterceptorProvider`: -```swift:title=NetworkInterceptorProvider.swift +```swift title="NetworkInterceptorProvider.swift" import Foundation import Apollo @@ -76,7 +76,7 @@ class NetworkInterceptorProvider: DefaultInterceptorProvider { Next, go back to your `Network` class. Replace the `ApolloClient` with an updated `lazy var` which creates the `RequestChainNetworkTransport` manually, using your custom interceptor provider: -```swift:title=Network.swift +```swift title="Network.swift" class Network { static let shared = Network() @@ -163,7 +163,7 @@ Now that you've fleshed out your operation, it's time to put it into the app. Go Build the application to run the code generation. Then, in `DetailViewController.swift`, fill in the `bookTrip` method with the code to book your trip based on the flight's ID: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private func bookTrip(with id: GraphQLID) { Network.shared.apollo.perform(mutation: BookTripMutation(id: id)) { [weak self] result in guard let self = self else { @@ -190,7 +190,7 @@ private func bookTrip(with id: GraphQLID) { Then, update the `cancelTrip` method print the ID of the flight being cancelled (you'll be adding the actual cancellation in the next step): -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private func cancelTrip(with id: GraphQLID) { print("Cancel trip \(id)") // TODO: Add code to cancel trip @@ -199,7 +199,7 @@ private func cancelTrip(with id: GraphQLID) { Next, update the `bookOrCancelTapped` method to use the two methods you've just added instead of `print`ing: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" if launch.isBooked { self.cancelTrip(with: launch.id) } else { @@ -209,7 +209,7 @@ if launch.isBooked { In `bookTrip`, replace the `TODO` with code to handle what comes back in the `success` property: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" if bookingResult.success { self.showAlert(title: "Success!", message: bookingResult.message ?? "Trip booked successfully") @@ -264,7 +264,7 @@ It works! Once again, go back to Xcode and create a new empty file, and name it Next, go to the `cancelTrip(with id:)` method in `DetailViewController.swift`. Replace the `print` statement with code that makes the call to cancel the trip: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" Network.shared.apollo.perform(mutation: CancelTripMutation(id: id)) { [weak self] result in guard let self = self else { return @@ -291,7 +291,7 @@ Network.shared.apollo.perform(mutation: CancelTripMutation(id: id)) { [weak self In `cancelTrip(with id:)`, replace the `TODO` with code to handle what comes back in that mutation's `success` property: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" if cancelResult.success { self.showAlert(title: "Trip cancelled", message: cancelResult.message ?? "Your trip has been officially cancelled.") @@ -319,7 +319,7 @@ There are [several different cache policies available to you](../caching/#specif Update the `loadLaunchDetails` method to take a parameter to determine if it should force reload. If it should force reload, update the cache policy from the default `.returnCacheDataElseFetch`, which will return data from the cache if it exists, to `.fetchIgnoringCacheData`: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" private func loadLaunchDetails(forceReload: Bool = false) { guard let launchID = self.launchID, @@ -343,10 +343,10 @@ private func loadLaunchDetails(forceReload: Bool = false) { Next, add the following line to **both** the `bookingResult.success` and `cancelResult.success` branches in their respective methods before showing the alerts: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" self.loadLaunchDetails(forceReload: true) ``` Run the application. When you book or cancel a trip, the application will fetch the updated state and update the UI with the correct state. When you go out and back in, the cache will be updated with the most recent state, and the most recent state will display. -In the next section, you'll learn how to use [subscriptions](/tutorial/tutorial-subscriptions/) with the Apollo client. +In the next section, you'll learn how to use [subscriptions](./tutorial-subscriptions/) with the Apollo client. diff --git a/docs/source/tutorial/tutorial-pagination.md b/docs/source/tutorial/tutorial-pagination.md index 9d7b710238..a82502e1cc 100644 --- a/docs/source/tutorial/tutorial-pagination.md +++ b/docs/source/tutorial/tutorial-pagination.md @@ -10,25 +10,25 @@ You're going to use a second section in the TableView to allow your user to load Add a variable to hold on to this object at the top of the `LaunchesViewController.swift` file near your `launches` variable: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private var lastConnection: LaunchListQuery.Data.Launch? ``` Next, you're going to take advantage of a type from the Apollo library. Add the following to the top of the file: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" import Apollo ``` Then, below `lastConnection`, add a variable to hang on to the most recent request: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private var activeRequest: Cancellable? ``` Next, add a second case to your `ListSection` enum: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" enum ListSection: Int, CaseIterable { case launches case loading @@ -41,7 +41,7 @@ This will also cause a number of errors because you're no longer exhaustively ha In `tableView(_:, numberOfRowsInSection:)`, add handling for the `.loading` case, which returns `0` if there are no more launches to load: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" case .loading: if self.lastConnection?.hasMore == false { return 0 @@ -54,7 +54,7 @@ Remember here that if `lastConnection` is nil, there *are* more launches to load Next, add handling for the `.loading` case to `tableView(_, cellForRowAt:)`, showing a different message based on whether there's an active request or not: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" case .loading: if self.activeRequest == nil { cell.textLabel?.text = "Tap to load more" @@ -69,7 +69,7 @@ To pass a variable into a GraphQL query, you need to use syntax that defines tha What does this look like in practice? Go to `LaunchList.graphql` and update just the first two lines to take and use the cursor as a parameter: -```graphql:title=LaunchList.graphql +```graphql title="LaunchList.graphql" query LaunchList($cursor:String) { launches(after:$cursor) { ``` @@ -78,7 +78,7 @@ Build the application so the code generation picks up on this new parameter. You Next, go back to `LaunchesViewController.swift` and update `loadLaunches()` to be `loadMoreLaunches(from cursor: String?)`, hanging on to the active request (and nil'ing it out when it completes), and updating the last received connection: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private func loadMoreLaunches(from cursor: String?) { self.activeRequest = Network.shared.apollo.fetch(query: LaunchListQuery(cursor: cursor)) { [weak self] result in guard let self = self else { @@ -114,7 +114,7 @@ private func loadMoreLaunches(from cursor: String?) { Then, add a new method to figure out if new launches need to be loaded: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private func loadMoreLaunchesIfTheyExist() { guard let connection = self.lastConnection else { // We don't have stored launch details, load from scratch @@ -133,7 +133,7 @@ private func loadMoreLaunchesIfTheyExist() { Update `viewDidLoad` to use this new method rather than calling `loadMoreLaunches(from:)` directly: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func viewDidLoad() { super.viewDidLoad() self.loadMoreLaunchesIfTheyExist() @@ -147,7 +147,7 @@ Luckily, you can use `UIViewController`'s `shouldPerformSegue(withIdentifier:se This method was already overridden in the starter project. Update the code within it to perform the segue for anything in the `.launches` section and _not_ perform it (instead loading more launches if needed) for the `.loading` section. Replace the `TODO` and everything below it with: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" guard let listSection = ListSection(rawValue: selectedIndexPath.section) else { assertionFailure("Invalid section") return false @@ -177,7 +177,7 @@ However, your code should theoretically never reach this point, so it's a good p Add the following to the `switch` statement in `prepare(for segue:)` -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" case .loading: assertionFailure("Shouldn't have gotten here!") ``` diff --git a/docs/source/tutorial/tutorial-query-ui.md b/docs/source/tutorial/tutorial-query-ui.md index a79ff3b55c..e008735d99 100644 --- a/docs/source/tutorial/tutorial-query-ui.md +++ b/docs/source/tutorial/tutorial-query-ui.md @@ -10,7 +10,7 @@ Now let's add properties to display the results of the `LaunchListQuery` you bui At the top of `LaunchesViewController.swift`, add a new property to store the launches that the query returns: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" var launches = [LaunchListQuery.Data.Launch.Launch]() ``` @@ -18,7 +18,7 @@ Why the long name? Each query returns its own nested object structure to ensure Next, add an enum that helps handle dealing with sections (we'll add more items to the enum later): -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" enum ListSection: Int, CaseIterable { case launches } @@ -30,7 +30,7 @@ Now we can update the various `UITableViewDataSource` methods to use the result For `numberOfSections(in:)`, you can use the `allCases` property from `CaseIterable` to provide the appropriate number of sections: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func numberOfSections(in tableView: UITableView) -> Int { return ListSection.allCases.count } @@ -38,7 +38,7 @@ override func numberOfSections(in tableView: UITableView) -> Int { For `tableView(_:numberOfRowsInSection:)`, you can try instantiating a `ListSection` enum object. If it doesn't work, that's an invalid section, and if it does, you can `switch` directly on the result. In this case, you'll want to return the count of launches: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { guard let listSection = ListSection(rawValue: section) else { assertionFailure("Invalid section") @@ -56,7 +56,7 @@ For `tableView(_:cellForRowAt:)`, you can use the existing cell dequeueing mecha For this initial section, grab a launch out of the `launches` array at the index of `indexPath.row`, and update the `textLabel` to display the launch site: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) @@ -83,7 +83,7 @@ However, you need to make sure that a call doesn't try to call back and use elem Replace the `TODO` in `loadLaunches` with the following: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private func loadLaunches() { Network.shared.apollo .fetch(query: LaunchListQuery()) { [weak self] result in @@ -117,7 +117,7 @@ This is why when you get a `GraphQLResult`, you generally want to check both the Replace the `// TODO` in the code above with the following code to handle both data and errors: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" if let launchConnection = graphQLResult.data?.launches { self.launches.append(contentsOf: launchConnection.launches.compactMap { $0 }) } @@ -133,7 +133,7 @@ if let errors = graphQLResult.errors { Finally, you'd normally need to actually call the method you just added to kick off the call to the network when the view is first loaded. Take a look at your `viewDidLoad` and note that it's already set up to call `loadLaunches`: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func viewDidLoad() { super.viewDidLoad() self.loadLaunches() @@ -158,7 +158,7 @@ Let's update the `DetailViewController` to be able to handle information about a Open `DetailViewController.swift` and note that there's a property below the list of `IBOutlet`s: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" var launchID: GraphQLID? { didSet { self.loadLaunchDetails() @@ -170,7 +170,7 @@ This settable property allows the `LaunchesViewController` to pass along the ide For now, update the `configureView()` method to use this property (if it's there) to show the launch's identifier: -```swift:title=DetailViewController.swift +```swift title="DetailViewController.swift" func configureView() { // Update the user interface for the detail item. guard @@ -188,7 +188,7 @@ func configureView() { Next, back in `LaunchesViewController.swift`, update the `prepareForSegue` method to obtain the most recently selected row and pass its corresponding launch details to the detail view controller. Replace the `TODO` and below with the following: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" guard let selectedIndexPath = self.tableView.indexPathForSelectedRow else { // Nothing is selected, nothing to do return @@ -228,7 +228,7 @@ Looking at the schema in Sandbox Explorer , you can see that `Launch` has a prop Because loading a table view with large images can impact performance, ask for the name and a `SMALL` mission patch. Update your query to look like the following: -```graphql:title=LaunchList.graphql +```graphql title="LaunchList.graphql" query LaunchList { launches { hasMore @@ -249,7 +249,7 @@ When you recompile, if you look in `API.swift`, you'll see a new nested type, `M Go back to `LaunchesViewController.swift` and add the following import of one of the libraries that was already in your project to the top of the file: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" import SDWebImage ``` @@ -263,7 +263,7 @@ You'll use this image as a placeholder to show while the mission patch images ar Now go back to `LaunchesViewController.swift`. In `tableView(cellForRowAt:)`, once the cell is loaded, add the following code to help make sure that before the cell is configured, it clears out any stale data: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" cell.imageView?.image = nil cell.textLabel?.text = nil cell.detailTextLabel?.text = nil @@ -273,7 +273,7 @@ cell.detailTextLabel?.text = nil Next, in the same method, go down to where you're setting up the cell based on the section. Update the code to use the launch mission name as the primary text label, the launch site as the detail text label, and to load the mission patch if it exists: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" switch listSection { case .launches: let launch = self.launches[indexPath.row] diff --git a/docs/source/tutorial/tutorial-subscriptions.md b/docs/source/tutorial/tutorial-subscriptions.md index b3a9c79daa..3ad4aed102 100644 --- a/docs/source/tutorial/tutorial-subscriptions.md +++ b/docs/source/tutorial/tutorial-subscriptions.md @@ -51,7 +51,7 @@ Continue booking and/or canceling trips, you will see events coming in the subsc Now that your subscription is working, add it to your project. Create an empty file named `TripsBooked.graphql` next to your other GraphQL files and paste the contents of the subscription. The process is similar to what you've already done for queries and mutations: -```graphql:title=TripsBooked.graphql +```graphql title="TripsBooked.graphql" subscription TripsBooked { tripsBooked } @@ -65,13 +65,13 @@ In `Network.swift`, you'll need to set up a transport which supports subscriptio First, at the top of the file, add an import for the **ApolloWebSocket** framework to get access to the classes you'll need: -```swift:title=Network.swift +```swift title="Network.swift" import ApolloWebSocket ``` Next, in the lazy declaration of the `apollo` variable, immediately after `transport` is declared, set up what you need to add subscription support to your client: -```swift:title=Network.swift +```swift title="Network.swift" // 1 let webSocket = WebSocket( url: URL(string: "wss://apollo-fullstack-tutorial.herokuapp.com/graphql")!, @@ -104,13 +104,13 @@ Now, you're ready to actually use your subscription! In `LaunchesViewController`, add a new variable just below `activeRequest` to hang on to a reference to your subscription so it doesn't get hammered by ARC as soon as it goes out of scope: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private var activeSubscription: Cancellable? ``` Next, just above the code for handling Segues, add code for starting and handling the result of a subscription: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" // MARK: - Subscriptions private func startSubscription() { @@ -139,7 +139,7 @@ private func handleSubscriptionEvent() { Finally, add a line to `viewDidLoad` which actually starts the subscription: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" override func viewDidLoad() { super.viewDidLoad() self.startSubscription() @@ -161,7 +161,7 @@ Trips booked: -1 Now, let's display that information in a view! Replace the `print` statement in `handleTripsBooked` with code to use the included `NotificationView` to show a brief alert at the bottom of the screen with information about a trip being booked or cancelled: -```swift:title=LaunchesViewController.swift +```swift title="LaunchesViewController.swift" private func handleTripsBooked(value: Int) { var message: String switch value { @@ -191,9 +191,9 @@ And you've done it! You've completed the tutorial. There are way more things you can do with the Apollo iOS SDK, and the rest of this documentation includes info on more advanced topics like: -- Using [fragments](/fragments/) -- Working with [custom scalars](/fetching-queries/#notes-on-working-with-custom-scalars) -- [Caching](/caching/) +- Using [fragments](../fragments/) +- Working with [custom scalars](../fetching-queries/#notes-on-working-with-custom-scalars) +- [Caching](../caching/) Feel free to ask questions by either [opening an issue on our GitHub repo](https://github.com/apollographql/apollo-ios/issues), or [joining the community](http://community.apollographql.com/new-topic?category=Help&tags=mobile,client). diff --git a/docs/source/watching-queries.md b/docs/source/watching-queries.md index 7191074cae..bc22e92139 100644 --- a/docs/source/watching-queries.md +++ b/docs/source/watching-queries.md @@ -2,5 +2,5 @@ title: Watching queries --- -[This information is now included in the Caching documentation.](/caching/) +[This information is now included in the Caching documentation.](./caching/)