1# Persisting Preferences Data 2 3 4## When to Use 5 6The **Preferences** module provides APIs for processing data in the form of key-value (KV) pairs, and supports persistence of the KV pairs when required, as well as modification and query of the data. You can use **Preferences** when you want a unique storage for global data. **Preferences** caches data in the memory, which allows fast access when the data is required. **Preferences** is recommended for storing small amount of data, such as personalized settings (font size and whether to enable the night mode) of applications. 7 8 9## Working Principles 10 11User applications call **Preference** through the JS interface to read and write data files. You can load the data of a **Preferences** persistence file to a **Preferences** instance. Each file uniquely corresponds to an instance. The system stores the instance in memory through a static container until the instance is removed from the memory or the file is deleted. The following figure illustrates how **Preference** works. 12 13The preference persistent file of an application is stored in the application sandbox. You can use **context** to obtain the file path. For details, see [Obtaining the Application Development Path](../application-models/application-context-stage.md#obtaining-the-application-development-path). 14 15**Figure 1** Preferences working mechanism 16 17![preferences](figures/preferences.jpg) 18 19 20## Constraints 21 22- The key in a KV pair must be a string and cannot be empty or exceed 80 bytes. 23 24- If the value is of the string type, it can be empty or a string not longer than 8192 bytes. 25 26- The memory usage increases with the amount of **Preferences** data. The maximum number of data records recommended is 10,000. Otherwise, high memory overheads will be caused. 27 28 29## Available APIs 30 31The following table lists the APIs used for preferences data persistence. Most of the APIs are executed asynchronously, using a callback or promise to return the result. The following table uses the callback-based APIs as an example. For more information about the APIs, see [User Preferences](../reference/apis/js-apis-data-preferences.md). 32 33| API| Description| 34| -------- | -------- | 35| getPreferences(context: Context, name: string, callback: AsyncCallback<Preferences>): void | Obtain a **Preferences** instance.| 36| put(key: string, value: ValueType, callback: AsyncCallback<void>): void | Writes data to the Preferences instance. You can use **flush()** to persist the **Preferences** instance data.| 37| has(key: string, callback: AsyncCallback<boolean>): void | Checks whether the **Preferences** instance contains a KV pair with the given key. The key cannot be empty.| 38| get(key: string, defValue: ValueType, callback: AsyncCallback<ValueType>): void | Obtains the value of the specified key. If the value is null or not of the default value type, **defValue** is returned.| 39| delete(key: string, callback: AsyncCallback<void>): void | Deletes the KV pair with the given key from the **Preferences** instance.| 40| flush(callback: AsyncCallback<void>): void | Flushes the data of this **Preferences** instance to a file for data persistence.| 41| on(type: 'change', callback: Callback<{ key : string }>): void | Subscribes to data changes of the specified key. When the value of the specified key is changed and saved by **flush()**, a callback will be invoked to return the new data.| 42| off(type: 'change', callback?: Callback<{ key : string }>): void | Unsubscribes from data changes.| 43| deletePreferences(context: Context, name: string, callback: AsyncCallback<void>): void | Deletes a **Preferences** instance from memory. If the **Preferences** instance has a persistent file, this API also deletes the persistent file.| 44 45 46## How to Develop 47 481. Import the **@ohos.data.preferences** module. 49 50 ```js 51 import dataPreferences from '@ohos.data.preferences'; 52 ``` 53 542. Obtain a **Preferences** instance. Read data from a file and load the data to a **Preferences** instance for data operations. 55 56 Stage model: 57 58 59 ```js 60 import UIAbility from '@ohos.app.ability.UIAbility'; 61 62 class EntryAbility extends UIAbility { 63 onWindowStageCreate(windowStage) { 64 try { 65 dataPreferences.getPreferences(this.context, 'mystore', (err, preferences) => { 66 if (err) { 67 console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`); 68 return; 69 } 70 console.info('Succeeded in getting preferences.'); 71 // Perform related data operations. 72 }) 73 } catch (err) { 74 console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`); 75 } 76 } 77 } 78 ``` 79 80 FA model: 81 82 83 ```js 84 import featureAbility from '@ohos.ability.featureAbility'; 85 86 // Obtain the context. 87 let context = featureAbility.getContext(); 88 89 try { 90 dataPreferences.getPreferences(context, 'mystore', (err, preferences) => { 91 if (err) { 92 console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`); 93 return; 94 } 95 console.info('Succeeded in getting preferences.'); 96 // Perform related data operations. 97 }) 98 } catch (err) { 99 console.error(`Failed to get preferences. Code is ${err.code},message:${err.message}`); 100 } 101 ``` 102 1033. Write data. 104 105 Use **put()** to write data to the **Preferences** instance. After data is written, you can use **flush()** to persist the **Preferences** instance data to a file if necessary. 106 107 > **NOTE** 108 > 109 > If the specified key already exists, the **put()** method changes the value. To prevent a value from being changed by mistake, you can use **has()** to check whether the KV pair exists. 110 111 Example: 112 113 114 ```js 115 try { 116 preferences.has('startup', function (err, val) { 117 if (err) { 118 console.error(`Failed to check the key 'startup'. Code:${err.code}, message:${err.message}`); 119 return; 120 } 121 if (val) { 122 console.info("The key 'startup' is contained."); 123 } else { 124 console.info("The key 'startup' does not contain."); 125 // Add a KV pair. 126 try { 127 preferences.put('startup', 'auto', (err) => { 128 if (err) { 129 console.error(`Failed to put data. Code:${err.code}, message:${err.message}`); 130 return; 131 } 132 console.info('Succeeded in putting data.'); 133 }) 134 } catch (err) { 135 console.error(`Failed to put data. Code: ${err.code},message:${err.message}`); 136 } 137 } 138 }) 139 } catch (err) { 140 console.error(`Failed to check the key 'startup'. Code:${err.code}, message:${err.message}`); 141 } 142 ``` 143 1444. Read data. 145 146 Use **get()** to obtain the value of the specified key. If the value is null or is not of the default value type, the default data is returned. 147 148 Example: 149 150 ```js 151 try { 152 preferences.get('startup', 'default', (err, val) => { 153 if (err) { 154 console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`); 155 return; 156 } 157 console.info(`Succeeded in getting value of 'startup'. val: ${val}.`); 158 }) 159 } catch (err) { 160 console.error(`Failed to get value of 'startup'. Code:${err.code}, message:${err.message}`); 161 } 162 ``` 163 1645. Delete data. 165 166 Use delete() to delete a KV pair.<br>Example: 167 168 169 ```js 170 try { 171 preferences.delete('startup', (err) => { 172 if (err) { 173 console.error(`Failed to delete the key 'startup'. Code:${err.code}, message:${err.message}`); 174 return; 175 } 176 console.info("Succeeded in deleting the key 'startup'."); 177 }) 178 } catch (err) { 179 console.error(`Failed to delete the key 'startup'. Code:${err.code}, message:${err.message}`); 180 } 181 ``` 182 1836. Persist data. 184 185 You can use **flush()** to persist the data held in a **Preferences** instance to a file. Example: 186 187 ```js 188 try { 189 preferences.flush((err) => { 190 if (err) { 191 console.error(`Failed to flush. Code:${err.code}, message:${err.message}`); 192 return; 193 } 194 console.info('Succeeded in flushing.'); 195 }) 196 } catch (err) { 197 console.error(`Failed to flush. Code:${err.code}, message:${err.message}`); 198 } 199 ``` 200 2017. Subscribe to data changes. 202 203 Specify an observer as the callback to return the data changes for an application. When the value of the subscribed key is changed and saved by **flush()**, the observer callback will be invoked to return the new data. Example: 204 205 ```js 206 let observer = function (key) { 207 console.info('The key' + key + 'changed.'); 208 } 209 preferences.on('change', observer); 210 // The data is changed from 'auto' to 'manual'. 211 preferences.put('startup', 'manual', (err) => { 212 if (err) { 213 console.error(`Failed to put the value of 'startup'. Code:${err.code},message:${err.message}`); 214 return; 215 } 216 console.info("Succeeded in putting the value of 'startup'."); 217 preferences.flush((err) => { 218 if (err) { 219 console.error(`Failed to flush. Code:${err.code}, message:${err.message}`); 220 return; 221 } 222 console.info('Succeeded in flushing.'); 223 }) 224 }) 225 ``` 226 2278. Delete a **Preferences** instance from the memory. 228 229 Use **deletePreferences()** to delete a **Preferences** instance from the memory. If the **Preferences** instance has a persistent file, the persistent file and its backup and corrupted files will also be deleted. 230 231 > **NOTE** 232 > 233 > - The deleted **Preferences** instance cannot be used for data operations. Otherwise, data inconsistency will be caused. 234 > 235 > - The deleted data and files cannot be restored. 236 237 Example: 238 239 240 ```js 241 try { 242 dataPreferences.deletePreferences(this.context, 'mystore', (err, val) => { 243 if (err) { 244 console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`); 245 return; 246 } 247 console.info('Succeeded in deleting preferences.'); 248 }) 249 } catch (err) { 250 console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`); 251 } 252 ```