1# Distributed Data Object Development 2 3## When to Use 4 5The **distributedDataObject** module provides APIs to implement data collaboration of the same application across multiple devices. In addition, the devices that form a Super Device can listen for object status and data changes with each other. 6 7For example, when the data of a distributed data object is added, deleted, or modified for application A on device 1, application A on device 2 can obtain the updated data. In addition, device 2 can listen for data changes and online/offline of the data objects on device 1. 8 9## Available APIs 10 11For details about the APIs, see [Distributed Data Object](../reference/apis/js-apis-data-distributedobject.md). 12 13### Creating a Distributed Data Object Instance 14 15Call **createDistributedObject()** to create a distributed data object instance. You can specify the attributes of the instance in **source**. 16 17 18**Table 1** API for creating a distributed data object instance 19 20| Bundle Name| API| Description| 21| -------- | -------- | -------- | 22| ohos.data.distributedDataObject| createDistributedObject(source: object): DistributedObject | Creates a distributed data object instance for data operations.<br>- **source**: attributes of the distributed data object to create.<br>- **DistributedObject**: returns the distributed data object created.| 23 24### Generating a Session ID 25 26Call **genSessionId()** to generate a session ID randomly. The generated session ID can be used to set the session ID of a distributed data object. 27 28**Table 2** API for generating a session ID randomly 29 30| Bundle Name| API| Description| 31| -------- | -------- | -------- | 32| ohos.data.distributedDataObject| genSessionId(): string | Generates a session ID, which can be used as the session ID of a distributed data object.| 33 34### Setting a Session ID for a Distributed Data Object 35 36Call **setSessionId()** to set a session ID for a distributed data object. The session ID is a unique identifier for one collaboration across devices. The distributed data objects to be synchronized must be associated with the same session ID. 37 38**Table 3** API for setting a session ID 39 40| Class| API| Description| 41| -------- | -------- | -------- | 42| DistributedDataObject | setSessionId(sessionId?: string): boolean | Sets a session ID for this distributed data object.<br>**sessionId**: ID of the distributed data object on a trusted network. To remove a distributed data object from the network, set this parameter to "" or leave it empty.| 43 44### Observing Data Changes 45 46Call **on()** to subscribe to data changes of a distributed data object. When the data changes, a callback will be invoked to return the data changes. You can use **off()** to unsubscribe from the data changes. 47 48**Table 4** APIs for observing data changes of a distributed data object 49 50| Class| API| Description| 51| -------- | -------- | -------- | 52| DistributedDataObject| on(type: 'change', callback: Callback<{ sessionId: string, fields: Array<string> }>): void | Subscribes to data changes.| 53| DistributedDataObject| off(type: 'change', callback?: Callback<{ sessionId: string, fields: Array<string> }>): void | Unsubscribes from data changes. <br/>**Callback**: callback to unregister. If this parameter is not specified, all data changes of this distributed data object will be unsubscribed from. | 54 55### Observing Online or Offline Status 56 57Call **on()** to subscribe to status changes of a distributed data object. The status can be online or offline. When the status changes, a callback will be invoked to return the status. You can use **off()** to unsubscribe from the status changes. 58 59**Table 5** APIs for observing status changes of a distributed data object 60 61| Class| API| Description| 62| -------- | -------- | -------- | 63| DistributedDataObject| on(type: 'status', callback: Callback<{ sessionId: string, networkId: string, status: 'online' \| 'offline' }>): void | Subscribes to the status changes of a distributed data object.| 64| DistributedDataObject| off(type: 'status', callback?: Callback<{ sessionId: string, deviceId: string, status: 'online' \| 'offline' }>): void | Unsubscribes from status changes of a distributed data object.| 65 66### Saving or Deleting a Distributed Data Object 67 68Call **save()** to save a distributed data object. When the application is active, the saved data will not be released. When the application exits and restarts, the data saved on the device will be restored. 69 70Call **revokeSave()** to delete a distributed data object that is no longer required. If the distributed data object is saved on the local device, **revokeSave()** will delete the data from all trusted devices. If the distributed data object is not saved on the local device, **revokeSave()** will delete the data from the local device. 71 72The saved data will be released in the following cases: 73 74- The data is stored for more than 24 hours. 75- The application has been uninstalled. 76- Data is successfully restored. 77 78**Table 6** APIs for saving and deleting a distributed data object 79 80| Class| API| Description| 81| -------- | -------- | -------- | 82| DistributedDataObject | save(deviceId: string): Promise<SaveSuccessResponse> | Saves a distributed data object.| 83| DistributedDataObject| revokeSave(): Promise<RevokeSaveSuccessResponse> | Deletes a distributed data object. | 84 85## How to Develop 86 87The following example shows how to implement distributed data object synchronization. 88 891. Import the @ohos.data.distributedDataObject module to the development environment. 90 91 ```js 92 import distributedObject from '@ohos.data.distributedDataObject'; 93 ``` 942. Apply for the permission. 95 96 Add the required permission (FA model) to the **config.json** file. 97 98 ```json 99 { 100 "module": { 101 "reqPermissions": [ 102 { 103 "name": "ohos.permission.DISTRIBUTED_DATASYNC" 104 } 105 ] 106 } 107 } 108 ``` 109 For the apps based on the stage model, see [Declaring Permissions](../security/accesstoken-guidelines.md#stage-model). 110 111 This permission must also be granted by the user when the application is started for the first time. 112 113 ```js 114 // FA model 115 import featureAbility from '@ohos.ability.featureAbility'; 116 117 function grantPermission() { 118 console.info('grantPermission'); 119 let context = featureAbility.getContext(); 120 context.requestPermissionsFromUser(['ohos.permission.DISTRIBUTED_DATASYNC'], 666, function (result) { 121 console.info(`requestPermissionsFromUser CallBack`); 122 123 }) 124 console.info('end grantPermission'); 125 } 126 127 grantPermission(); 128 ``` 129 130 ```ts 131 // Stage model 132 import UIAbility from '@ohos.app.ability.UIAbility'; 133 134 let context = null; 135 136 class EntryAbility extends UIAbility { 137 onWindowStageCreate(windowStage) { 138 context = this.context; 139 } 140 } 141 142 function grantPermission() { 143 let permissions = ['ohos.permission.DISTRIBUTED_DATASYNC']; 144 context.requestPermissionsFromUser(permissions).then((data) => { 145 console.info('success: ${data}'); 146 }).catch((error) => { 147 console.error('failed: ${error}'); 148 }); 149 } 150 151 grantPermission(); 152 ``` 153 1543. Obtain a distributed data object instance. 155 156 ```js 157 let localObject = distributedObject.createDistributedObject({ 158 name: undefined, 159 age: undefined, 160 isVis: true, 161 parent: undefined, 162 list: undefined 163 }); 164 let sessionId = distributedObject.genSessionId(); 165 ``` 166 1674. Add the distributed data object instance to a network for data synchronization. The data objects in the synchronization network include the local and remote objects. 168 169 ```js 170 // Local object 171 let localObject = distributedObject.createDistributedObject({ 172 name: "jack", 173 age: 18, 174 isVis: true, 175 parent: { mother: "jack mom", father: "jack Dad" }, 176 list: [{ mother: "jack mom" }, { father: "jack Dad" }] 177 }); 178 localObject.setSessionId(sessionId); 179 180 // Remote object 181 let remoteObject = distributedObject.createDistributedObject({ 182 name: undefined, 183 age: undefined, 184 isVis: true, 185 parent: undefined, 186 list: undefined 187 }); 188 // After learning that the local device goes online, the remote object synchronizes data. That is, name changes to jack and age to 18. 189 remoteObject.setSessionId(sessionId); 190 ``` 191 1925. Observe the data changes of the distributed data object. You can subscribe to data changes of the remote object. When the data in the remote object changes, a callback will be invoked to return the data changes. 193 194 ```js 195 function changeCallback(sessionId, changeData) { 196 console.info("change" + sessionId); 197 198 if (changeData != null && changeData != undefined) { 199 changeData.forEach(element => { 200 console.info("changed !" + element + " " + localObject[element]); 201 }); 202 } 203 } 204 205 // To refresh the page in changeCallback, correctly bind (this) to the changeCallback. 206 localObject.on("change", this.changeCallback.bind(this)); 207 ``` 208 2096. Modify attributes of the distributed data object. The object attributes support basic data types (such as number, Boolean, and string) and complex data types (array and nested basic types). 210 211 ```js 212 localObject.name = "jack"; 213 localObject.age = 19; 214 localObject.isVis = false; 215 localObject.parent = { mother: "jack mom", father: "jack Dad" }; 216 localObject.list = [{ mother: "jack mom" }, { father: "jack Dad" }]; 217 ``` 218 219 > **NOTE**<br> 220 > For the distributed data object of the complex type, only the root attribute can be modified. The subordinate attributes cannot be modified. 221 222 ```js 223 // Supported modification. 224 localObject.parent = { mother: "mom", father: "dad" }; 225 // Modification not supported. 226 localObject.parent.mother = "mom"; 227 ``` 228 2297. Access the distributed data object.<br>Obtain the distributed data object attributes, which are the latest data on the network. 230 231 ```js 232 console.info("name " + localObject["name"]); 233 ``` 2348. Unsubscribe from data changes. You can specify the callback to unregister. If you do not specify the callback, all data change callbacks of the distributed data object will be unregistered. 235 236 ```js 237 // Unregister the specified data change callback. 238 localObject.off("change", changeCallback); 239 // Unregister all data change callbacks. 240 localObject.off("change"); 241 ``` 2429. Subscribe to status changes of this distributed data object. A callback will be invoked to report the status change when the target distributed data object goes online or offline. 243 244 ```js 245 function statusCallback(sessionId, networkId, status) { 246 this.response += "status changed " + sessionId + " " + status + " " + networkId; 247 } 248 249 localObject.on("status", this.statusCallback); 250 ``` 251 25210. Save a distributed data object and delete it. 253 254 ```js 255 // Save a distributed data object. 256 localObject.save("local").then((result) => { 257 console.info("save sessionId " + result.sessionId); 258 console.info("save version " + result.version); 259 console.info("save deviceId " + result.deviceId); 260 }, (result) => { 261 console.info("save local failed."); 262 }); 263 // Revoke the data saving operation. 264 localObject.revokeSave().then((result) => { 265 console.info("revokeSave success."); 266 }, (result) => { 267 console.info("revokeSave failed."); 268 }); 269 ``` 27011. Unsubscribe from the status changes of this distributed data object. You can specify the callback to unregister. If you do not specify the callback, this API unregisters all status change callbacks of this distributed data object. 271 272 ```js 273 // Unregister the specified status change callback. 274 localObject.off("status", this.statusCallback); 275 // Unregister all status change callbacks. 276 localObject.off("status"); 277 ``` 27812. Remove the distributed data object from the synchronization network. The data changes on the local object will not be synchronized to the removed distributed data object. 279 280 ```js 281 localObject.setSessionId(""); 282 ``` 283