Cache setup
All caches used by the ApolloClient
must conform to the NormalizedCache
protocol. This protocol provides normalized cache entries as serialized key value pairs called Records
.
In addition to the default cache implementations provided by Apollo iOS, you can create your own cache, providing any custom storage implementation you like. Because the records provided to your NormalizedCache
implementation have already been "normalized" by Apollo iOS, you can focus your implementation on the storage of your normalized cache data.
If you are interested in creating a custom
NormalizedCache
implementation, start by reading the API Reference forNormalizedCache
.
Apollo iOS includes default implementations for two types of NormalizedCache
:
InMemoryNormalizedCache
This is the default caching implementation used by the ApolloClient
.
An in-memory cache stores normalized results directly in system memory while your application is running. Results are not persisted to disk. This means the cache is not saved when the application terminates.
Because the cached data is stored directly in memory, it is faster to read and write records to the cache than a disk-based cache implementation.
An in-memory cache is best at caching short-lived data. It is recommended for data that is expected to change frequently or is unlikely to be accessed again in the future.
A few examples of this are:
Items in a newsfeed
Location-based data
Search results for a specific search term
For data that is short-lived, the simplicity of having a clear cache at the beginning of each application run, combined with the improved performance, may make an InMemoryNormalizedCache
a good choice.
InMemoryNormalizedCache
does not implement any auto-eviction policies. This means your application is responsible for reacting to any low memory notifications and taking action to either clear the cache or remove select records.Setup
To use an InMemoryNormalizedCache
, no additional work is necessary!
InMemoryNormalizedCache
is the default cache when initializing an ApolloClient
. If you want to use an in-memory cache without modifications, all you have to do is instantiate an ApolloClient
instance without passing a custom ApolloStore
into the store
parameter.
If you find you need to instantiate the in-memory cache yourself, you can do so with one line:
1let cache = InMemoryNormalizedCache()
SQLiteNormalizedCache
A SQLite cache writes out cache results to an on-disk SQLite
file.
Storing cache results on-disk allows us to maintain the cache across application runs. However the file I/O required by each cache operation may slightly increase cache response time.
As an added benefit, because this cache does not hold any results in memory, there is no risk of the cache using too much memory.
An on-disk cache is best at caching long-lived data. It is recommended for data that is not expected to change as frequently as it is accessed; takes a long time to fetch; or should be accessible while offline.
A few examples of this are:
User Settings/Profiles
Locally created user content
Data from background fetches
For data that you want to persist between application runs, the SQLiteNormalizedCache
may fit your needs.
Setup
To use the SQLiteNormalizedCache
, you need to add the ApolloSQLite
sub-package to your project using your preferred package manager:
Adding SQLite with Swift Package Manager
dependencies
in your Package.swift
file:1.product(name: "ApolloSQLite", package: "Apollo"),
Adding SQLite with CocoaPods
Podfile
:1pod 'Apollo'
2pod 'Apollo/SQLite'
Apollo
, you need to specify the same version for Apollo/SQLite
.Once ApolloSQLite
is linked to your project, you can do the following:
Set up a file URL for your
SQLite
file.Use that file URL to instantiate a
SQLiteNormalizedCache
.Instantiate an
ApolloStore
with yourSQLiteNormalizedCache
.Pass that
ApolloStore
into the initializer ofApolloClient
:
1// 1. Determine where you would like to store your SQLite file.
2// A commonly used location is the user's Documents directory
3// within your application's sandbox.
4let documentsPath = NSSearchPathForDirectoriesInDomains(
5 .documentDirectory,
6 .userDomainMask,
7 true
8).first!
9let documentsURL = URL(fileURLWithPath: documentsPath)
10let sqliteFileURL = documentsURL.appendingPathComponent("test_apollo_db.sqlite")
11
12// 2. Use that file URL to instantiate the SQLite cache:
13let sqliteCache = try SQLiteNormalizedCache(fileURL: sqliteFileURL)
14
15// 3. And then instantiate an instance of `ApolloStore` with the cache you've just created:
16let store = ApolloStore(cache: sqliteCache)
17
18// 4. Assuming you've set up your `networkTransport` instance elsewhere,
19// pass the store you just created into your `ApolloClient` initializer.
20let apolloClient = ApolloClient(networkTransport: networkTransport, store: store)