|
1 | 1 |
|
2 | 2 | # Offline mode
|
3 | 3 |
|
4 |
| -**Table of contents** |
5 |
| - |
6 |
| -* [Overview](#overview) |
7 |
| -* [Setup](#setup) |
8 |
| -* [Usage](#usage) |
9 |
| -* [Unsupported features](#unsupported-features) |
10 |
| -* [Troubleshooting](#troubleshooting) |
11 |
| -* [Other resources](#other-resources) |
12 |
| - |
13 |
| - |
14 |
| -## Overview |
15 |
| - |
16 |
| -The API client can be enhanced with offline capabilities. This optional **offline mode** allows you to mirror online indices on local storage, and transparently switch to the local mirror in case of unavailability of the online index, thus providing uninterrupted user experience. You can also explicitly query the mirror if you want. |
17 |
| - |
18 |
| -Because indices can be arbitrarily big, whereas mobile devices tend to be constrained by network bandwidth, disk space or memory consumption, only part of an index's data is usually synchronized (typically the most popular entries, or what's relevant to the user, or close to her location...). The offline mode lets you control which data subset you want to synchronize, and how often to synchronize it. |
19 |
| - |
20 |
| -Index settings are automatically synchronized, so that your local index will behave exactly as your online index, with a few restrictions: |
21 |
| - |
22 |
| -- If only part of the data is mirrored, queries may obviously return less objects. Counts (hits, facets...) may also differ. |
23 |
| - |
24 |
| -- Some advanced features are not supported offline. See [Unsupported features](#unsupported-features) for more information. |
25 |
| - |
26 |
| - |
27 |
| -### Availability |
28 |
| - |
29 |
| -Offline features are brought by Algolia's **Offline SDK**, which is actually composed of two separate components: |
30 |
| - |
31 |
| -- The **Offline API Client** is a superset of the regular, online API client (so all your existing code will work without any modification). It is open source; the source code is available on GitHub in the same repository as the online [Android API client](https://github.com/algolia/algoliasearch-client-android). |
32 |
| - |
33 |
| -- The **Offline Core** is a closed source component using native libraries. Although it is readily available for download, *it is licensed separately*, and will not work without a valid **license key**. Please [contact us](https://www.algolia.com/) for more information. |
34 |
| - |
35 |
| - |
36 |
| - |
37 |
| -## Setup |
38 |
| - |
39 |
| -### Prerequisites |
40 |
| - |
41 |
| -- Obtain a **license key** from [Algolia](https://www.algolia.com/). |
42 |
| - |
43 |
| -- Make sure you use an **API key** with the search (`search`), browse (`browse`) and get index settings (`settings`) ACLs. *This is required because the offline mode needs to replicate the online index's settings and uses browse requests when syncing.* |
44 |
| - |
45 |
| - |
46 |
| -### Steps |
47 |
| - |
48 |
| - |
49 |
| -### Steps |
50 |
| - |
51 |
| -- In your Gradle script, use the `algoliasearch-offline-android` package in place of `algoliasearch-android`. Typically: |
52 |
| - |
53 |
| - ```groovy |
54 |
| - dependencies { |
55 |
| - // [...] other dependencies |
56 |
| - compile "com.algolia:algoliasearch-offline-android:$LATEST_VERSION_HERE@aar" |
57 |
| - } |
58 |
| - ``` |
59 |
| -
|
60 |
| -- When initializing your client, instantiate an `OfflineClient` instead of a `Client`:. |
61 |
| -
|
62 |
| - ```java |
63 |
| - client = new OfflineClient(context, "YOUR_APP_ID", "YOUR_API_KEY"); |
64 |
| - ``` |
65 |
| -
|
66 |
| - ... where `context` is a valid Android `Context`. |
67 |
| -
|
68 |
| - By default, the client will store data for local indices in an `algolia` subdirectory of the application's files directory. Alternatively, you may specify it during the instantiation of the client. |
69 |
| -
|
70 |
| - **Warning:** Although using the cache directory may be tempting, we advise you against doing so. There is no guarantee that all files will be deleted together, and a partial delete could leave an index in an inconsistent state. |
71 |
| -
|
72 |
| -- **Enable offline mode**: |
73 |
| -
|
74 |
| - ```java |
75 |
| - client.enableOfflineMode("YOUR_OFFLINE_CORE_LICENSE_KEY") |
76 |
| - ``` |
77 |
| -
|
78 |
| -
|
79 |
| -## Usage |
80 |
| -
|
81 |
| -### Activation |
82 |
| -
|
83 |
| -An `OfflineClient` provides all the features of an online `Client`. It returns `MirroredIndex` instances, which also provide all the features of online `Index` instances. |
84 |
| -
|
85 |
| -However, until you explicitly enable the offline mode by calling `enableOfflineMode()`, your offline client behaves like a regular online client. The same goes for indices: *you must explicitly activate mirroring* by calling `setMirrored(true)`. The reason is that you might not want to mirror all of your indices. |
86 |
| -
|
87 |
| -*Warning: Calling offline features before enabling mirroring on an index is a programming error and will be punished by an `IllegalStateException`.* |
88 |
| -
|
89 |
| -
|
90 |
| -### Synchronization |
91 |
| -
|
92 |
| -You have entire control over **what** is synchronized and **when**. |
93 |
| -
|
94 |
| -#### What |
95 |
| -
|
96 |
| -First, specify what subset of the data is to be synchronized. You do so by constructing **data selection queries** and calling `MirroredIndex.setDataSelectionQueries()`. |
97 |
| -
|
98 |
| -A *data selection query* is essentially a combination of a browse `Query` and a maximum object count. When syncing, the offline index will browse the online index, filtering objects through the provided query (which can be empty, hence selecting all objects), and stopping when the maximum object count has been reached (or at the end of the index, whichever comes first). |
99 |
| -
|
100 |
| -It will do so for every data selection query you have provided, then build (or re-build) the local index from the retrieved data. (When re-building, the previous version of the local index remains available for querying, until it is replaced by the new version.) |
101 |
| -
|
102 |
| -**Warning:** The entire selected data is re-downloaded at every sync, so be careful about bandwidth usage! |
103 |
| -
|
104 |
| -*Warning: It is a programming error to attempt a sync with no data selection queries. Doing so will result in an `IllegalStateException` being thrown.* |
105 |
| -
|
106 |
| -**Note:** Because the sync uses a "browse" to retrieve objects, the number of objects actually mirrored may exceed the maximum object count specified in the data selection query (up to one page of results of difference). |
107 |
| -
|
108 |
| -
|
109 |
| -#### When |
110 |
| -
|
111 |
| -The easiest way to synchronize your index is to use the **semi-automatic mode**: |
112 |
| -
|
113 |
| -- Choose a minimum delay between two syncs by calling `MirroredIndex.setDelayBetweenSyncs()`. The default is 24 hours. |
114 |
| -
|
115 |
| -- Whenever conditions are met for a potential sync (e.g. the device is online), call `MirroredIndex.syncIfNeeded()`. If the last successful sync is older than the minimum delay, a sync will be launched. Otherwise, the call will be ignored. |
116 |
| -
|
117 |
| -Alternatively, you may call `MirroredIndex.sync()` to force a sync to happen now. |
118 |
| -
|
119 |
| -The reason you have to choose when to synchronize is that the decision depends on various factors that the SDK cannot know, in particular the specific business rules of your application, or the user's preferences. For example, you may want to sync only when connected to a non-metered Wi-Fi network, or during the night. |
120 |
| -
|
121 |
| -**Note:** Syncs always happen in the background, and therefore should not impact the user's experience. |
122 |
| -
|
123 |
| -**Note:** You cannot have two syncs on the same index running in parallel. If a sync is already running, concurrent sync requests will be ignored. |
124 |
| -
|
125 |
| -
|
126 |
| -### Querying |
127 |
| -
|
128 |
| -#### Transparent fallback mode |
129 |
| -
|
130 |
| -You query a mirrored index using the same `search()` method as a purely online index. This will use the offline mirror as a fallback in case of failure of the online request. |
131 |
| -
|
132 |
| -You can customize this behavior by changing the `requestStrategy` property of the index: |
133 |
| -
|
134 |
| -- `FallbackOnFailure` (default) only falls back to the offline mirror if the online request fails. This covers cases where the device is offline; however, when the device is online but with a bad connectivity, every timeout has to be hit before the request is considered a failure. |
135 |
| -
|
136 |
| -- To enforce a maximum response time, you can use `FallbackOnTimeout`, adjusting the timeout threshold via the `offlineFallbackTimeout` property. |
137 |
| -
|
138 |
| -- `OnlineOnly` and `OfflineOnly` are rather straightforward strategies, meant to implement custom strategies on top of them. |
139 |
| -
|
140 |
| -#### Data origin |
141 |
| -
|
142 |
| -The origin of the data is indicated by the `origin` attribute in the returned result object: its value is `remote` if the content originates from the online API, and `local` if the content originates from the offline mirror. When you are using a mixed online/offline request strategy (the default, see above), this lets you know where the response is coming from. |
143 |
| -
|
144 |
| -
|
145 |
| -#### Direct query |
146 |
| -
|
147 |
| -You may directly target the offline mirror if you want: |
148 |
| -
|
149 |
| -- for search queries: `searchOffline()` |
150 |
| -- for browse queries: `browseMirror()` and `browseMirrorFrom()` |
151 |
| -
|
152 |
| -Those methods have the same semantics as their online counterpart. |
153 |
| -
|
154 |
| -Browsing is especially relevant when synchronizing [associated resources](#associated-resources). |
155 |
| -
|
156 |
| -
|
157 |
| -### Events |
158 |
| -
|
159 |
| -You may be informed of sync events by registering a `SyncListener` on a `MirroredIndex` instance (using `addSyncListener()`). |
160 |
| -
|
161 |
| -
|
162 |
| -### Associated resources |
163 |
| -
|
164 |
| -In a typical setup, objects from an index are not standalone. Rather, they reference other resources (for example images) that are stored outside of Algolia. They are called **associated resources**. |
165 |
| -
|
166 |
| -In order to offer the best user experience, you may want to pre-load some of those resources while you are online, so that they are available when offline. |
167 |
| -
|
168 |
| -To do so: |
169 |
| -
|
170 |
| -- register a listener on the mirrored index (see [Events](#events) above); |
171 |
| -- when the sync is finished, browse the local mirror (using `browseMirror()` and `browseMirrorFrom()`, see above), parsing each object to detect associated resources; |
172 |
| -- pre-fetch those that are not already available locally. |
173 |
| -
|
174 |
| -**Note:** You should do so from a background thread with a low priority to minimize impact on the user's experience. |
175 |
| -
|
176 |
| -
|
177 |
| -
|
178 |
| -## Unsupported features |
179 |
| -
|
180 |
| -Due mainly to binary size constraints, the following features are not supported by the offline mode: |
181 |
| -
|
182 |
| -- plurals dictionary (simple plurals with a final S are still handled) |
183 |
| -- CJK segmentation |
184 |
| -- IP geolocation (`aroundLatLngViaIP` query parameter) |
185 |
| -
|
186 |
| -
|
187 |
| -
|
188 |
| -## Troubleshooting |
189 |
| -
|
190 |
| -### Logs |
191 |
| -
|
192 |
| -The SDK logs messages using the regular Android logging system, which can be useful when troubleshooting. |
193 |
| -
|
194 |
| -If the SDK does not seem to work, first check for proper initialization in the logs. You should see something like: |
195 |
| -
|
196 |
| -``` |
197 |
| -Algolia SDK v1.2.3 |
198 |
| -Algolia SDK licensed to: Peanuts, Inc. |
199 |
| -``` |
200 |
| -
|
201 |
| -Any unexpected condition should result in a warning/error being logged. |
202 |
| -
|
203 |
| -
|
204 |
| -### Support |
205 |
| -
|
206 |
| -If you think you found a bug in the offline client, please submit an issue on GitHub so that it can benefit the community. |
207 |
| -
|
208 |
| -If you have a crash in the offline core, please send us a support request. Make sure to include the **crash report**, so that we can pinpoint the problem. |
209 |
| -
|
210 |
| -
|
211 |
| -## Other resources |
212 |
| -
|
213 |
| -The offline client bears extensive documentation comments. Please refer to them for more details. |
| 4 | +**This document has moved** to <https://www.algolia.com/doc/offline-mode/android>. |
0 commit comments