diff --git a/docs/shared/sqlite-carthage-panel.mdx b/docs/shared/sqlite-carthage-panel.mdx new file mode 100644 index 0000000000..16eb1e272a --- /dev/null +++ b/docs/shared/sqlite-carthage-panel.mdx @@ -0,0 +1,11 @@ +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 new file mode 100644 index 0000000000..37a8eade5a --- /dev/null +++ b/docs/shared/sqlite-cocoapods-panel.mdx @@ -0,0 +1,18 @@ +import { + ExpansionPanel, + ExpansionPanelList, + ExpansionPanelListItem +} from 'gatsby-theme-apollo-docs'; + + + +Add the following to your `Podfile`: + +```ruby +pod 'Apollo' +pod 'Apollo/SQLite' +``` + +Note that if you're specifying a version for `Apollo`, you need to specify the same version for `Apollo/SQLite`. + + \ No newline at end of file diff --git a/docs/shared/sqlite-spm-panel.mdx b/docs/shared/sqlite-spm-panel.mdx new file mode 100644 index 0000000000..ef9b20621a --- /dev/null +++ b/docs/shared/sqlite-spm-panel.mdx @@ -0,0 +1,19 @@ +import { + ExpansionPanel, + ExpansionPanelList, + ExpansionPanelListItem +} from 'gatsby-theme-apollo-docs'; + + + +Add the following to your `Package.swift`: + +```swift +.target( + name: "MyApplication", + dependencies: [ + .product(name: "ApolloSQLite", package: "Apollo"), + ]) +``` + + \ No newline at end of file diff --git a/docs/source/caching.md b/docs/source/caching.mdx similarity index 73% rename from docs/source/caching.md rename to docs/source/caching.mdx index cc0f449484..78450ada37 100644 --- a/docs/source/caching.md +++ b/docs/source/caching.mdx @@ -2,6 +2,10 @@ title: Client-side caching --- +import SPMSQLite from "../shared/sqlite-spm-panel.mdx" +import CocoaPodsSQLite from "../shared/sqlite-cocoapods-panel.mdx" +import CarthageSQLite from "../shared/sqlite-carthage-panel.mdx" + As mentioned in the introduction, Apollo iOS does more than simply run your queries against a GraphQL server. It normalizes query results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run. This means your UI is always internally consistent, and can be kept fully up-to-date with the state on the server with the minimum number of queries required. @@ -15,6 +19,69 @@ All caches used by the `ApolloClient` must conform to the [`NormalizedCache` pro All caches can be cleared in their entirety by calling [`clear(callbackQueue:completion:)`](api/Apollo/protocols/NormalizedCache/#clearcallbackqueuecompletion). If you need to work more directly with the cache, please see the [Direct Cache Access](#direct-cache-access) section. +## Cache Setup + +### In-Memory Cache + +For `InMemoryNormalizedCache`, no sub-libraries are needed. + +This type of cache is used by default when setting up an `ApolloClient`. If you want to use an in-memory cache without modifications, all you have to do is instantiate an `ApolloClient` instance and not pass anything into the `store` parameter. + +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 +import Apollo + +let cache = InMemoryNormalizedCache() +``` + +### SQLite Cache + +To use the `SQLiteNormalizedCache`, you need to add the `ApolloSQLite` sub-library to your project using your preferred package manager: + + + + + + + +Once added, you can do the following: + +1. Set up a file URL for your `SQLite` file. +2. Use that file URL to instantiate a SQLite cache. +3. Use that SQLite cache to instantiate an `ApolloStore`. +4. Pass that `ApolloStore` into the initializer of `ApolloClient`: + +```swift:title=Client%20Setup +import Apollo + +// NOTE: You need this import line if you are **NOT** using CocoaPods. In CocoaPods, +// ApolloSQLite files are collapsed into the Apollo framework. For other dependency managers, +// ApolloSQLite is a separate framework. +import ApolloSQLite + +// 1. You'll have to figure out where to store your SQLite file. +// A reasonable place is the user's Documents directory in your sandbox. +// In any case, create a file URL for your file: +let documentsPath = NSSearchPathForDirectoriesInDomains( + .documentDirectory, + .userDomainMask, + true).first! +let documentsURL = URL(fileURLWithPath: documentsPath) +let sqliteFileURL = documentsURL.appendingPathComponent("test_apollo_db.sqlite") + +// 2. Use that file URL to instantiate the SQLite cache: +let sqliteCache = try SQLiteNormalizedCache(fileURL: sqliteFileURL) + +// 3. And then instantiate an instance of `ApolloStore` with the cache you've just created: +let store = ApolloStore(cache: sqliteCache) + +// 4. Assuming you've set up your `networkTransport` instance elsewhere, +// pass the store you just created into your `ApolloClient` initializer, +// and you're now set up to use the SQLite cache for persistent storage +let apolloClient = ApolloClient(networkTransport: networkTransport, store: store) +``` + ## Controlling normalization While Apollo can do basic caching based on the shape of GraphQL queries and their results, Apollo won't be able to associate objects fetched by different queries without additional information about the identities of the objects returned from the server. @@ -107,4 +174,4 @@ store.withinReadWriteTransaction({ transaction in print(graphQLResult?.data?.hero?.name) } }) -``` \ No newline at end of file +```