OLD | NEW |
(Empty) | |
| 1 <h1>Manage Data</h1> |
| 2 |
| 3 |
| 4 <p> |
| 5 Almost every aspect of app development involves some element |
| 6 of sending or receiving data. |
| 7 Starting with the basics, |
| 8 you should use an MVC framework to help you design and implement your app |
| 9 so that data is completely separate from the app's view on that data |
| 10 (see <a href="app_frameworks.html">MVC Architecture</a>). |
| 11 </p> |
| 12 |
| 13 <p> |
| 14 You also need to think about how data is handled when your app is offline |
| 15 (see <a href="offline_apps.html">Offline First</a>). |
| 16 This doc briefly introduces the storage options |
| 17 for sending, receiving, and saving data locally; |
| 18 the remainder of the doc shows you how |
| 19 to use Chrome's File System API |
| 20 (see also the <a href="fileSystem.html">fileSystem API</a>). |
| 21 </p> |
| 22 |
| 23 <p class="note"> |
| 24 <b>API Samples: </b> |
| 25 Want to play with the code? |
| 26 Check out the |
| 27 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/filesyst
em-access">filesystem-access</a> |
| 28 and <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/stor
age">storage</a> samples. |
| 29 </p> |
| 30 |
| 31 <h2 id="options">Storage options</h2> |
| 32 |
| 33 <p> |
| 34 Packaged apps use many different mechanisms |
| 35 to send and receive data. |
| 36 For external data (resources, web pages), |
| 37 you need to be aware of the |
| 38 <a href="app_csp.html">Content Security Policy (CSP)</a>. |
| 39 Similar to Chrome Extensions, |
| 40 you can use |
| 41 <a href="app_external.html#external">cross-origin XMLHttpRequests</a> |
| 42 to communicate with remote servers. |
| 43 You can also isolate external pages, |
| 44 so that the rest of your app is secure |
| 45 (see <a href="app_external.html#objecttag">Embed external web pages</a>). |
| 46 With Web Intents, |
| 47 your app can share data with other apps |
| 48 (see <a href="app_intents.html">Connect Apps with Web Intents</a>). |
| 49 </p> |
| 50 |
| 51 <p> |
| 52 When saving data locally, |
| 53 you can use the <a href="storage.html">Chrome Storage API</a> |
| 54 to save small amounts of string data and |
| 55 IndexedDB to save structured data. |
| 56 With IndexedDB, you can persist JavaScript objects |
| 57 to an object store and use the store's indexes to query data |
| 58 (to learn more, see HTML5 Rock's |
| 59 <a href="http://www.html5rocks.com/tutorials/indexeddb/todo/">Simple Todo List T
utorial</a>). |
| 60 For all other types of data, |
| 61 like binary data, |
| 62 use the Filesystem API. |
| 63 </p> |
| 64 |
| 65 <p> |
| 66 Chrome's Filesystem API extends the |
| 67 <a href="http://www.html5rocks.com/tutorials/file/filesystem/">HTML5 FileSystem
API</a>; |
| 68 apps can create, read, navigate, |
| 69 and write to a sandboxed section |
| 70 of the user's local file system. |
| 71 With Chrome's File System API, |
| 72 packaged apps can read and write files |
| 73 to user-selected locations. |
| 74 For example, |
| 75 a photo-sharing app can use the File System API |
| 76 to read and write any photos that a user selects. |
| 77 </p> |
| 78 |
| 79 <h2 id="manifest">Adding file system permission</h2> |
| 80 |
| 81 <p> |
| 82 To use Chrome's File System API, |
| 83 you need to add the "fileSystem" permission to the manifest, |
| 84 so that you can obtain permission from the user |
| 85 to store persistent data. |
| 86 |
| 87 <pre> |
| 88 "permissions": [ |
| 89 "...", |
| 90 "fileSystem" |
| 91 ] |
| 92 </pre> |
| 93 |
| 94 <h2 id="import">User-options for selecting files</h2> |
| 95 |
| 96 <p> |
| 97 Users expect to select files |
| 98 in the same way they always do. |
| 99 At a minimum, |
| 100 they expect a 'choose file' button |
| 101 and standard file-chooser. |
| 102 If your app makes heavy use of file-handing, |
| 103 you should also implement drag-and-drop |
| 104 (see below and also check out |
| 105 <a href="http://www.html5rocks.com/tutorials/dnd/basics/">Native HTML5 Drag and
Drop</a>). |
| 106 </p> |
| 107 |
| 108 <p> |
| 109 If your app connects with other apps using |
| 110 <a href="app_intents.html">Web Intents</a> |
| 111 you can set up data sharing with those apps. |
| 112 Users can view and/or write |
| 113 to their files using a connected app |
| 114 without having to do all sorts of extra steps |
| 115 to move files back and forth. |
| 116 </p> |
| 117 |
| 118 <h2 id="path">Obtaining the path of a fileEntry</h2> |
| 119 |
| 120 <p> |
| 121 To get the full path |
| 122 of the file the user selected, |
| 123 <code>fileEntry</code>, |
| 124 call <code>getDisplayPath()</code>: |
| 125 </p> |
| 126 |
| 127 <pre> |
| 128 function displayPath(fileEntry) { |
| 129 chrome.fileSystem.getDisplayPath(fileEntry, function(path) { |
| 130 console.log(path) |
| 131 }); |
| 132 } |
| 133 </pre> |
| 134 |
| 135 <h2 id="drag">Implementing drag-and-drop</h2> |
| 136 |
| 137 <p> |
| 138 If you need to implement drag-and-drop selection, |
| 139 the drag-and-drop file controller |
| 140 (<code>dnd.js</code>) in |
| 141 the <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/file
system-access">filesystem-access</a> |
| 142 sample is a good starting point. |
| 143 The controller creates a file entry |
| 144 from a <code>DataTransferItem</code> |
| 145 via drag-and-drop. |
| 146 In this example, |
| 147 the <code>fileEntry</code> is set |
| 148 to the first dropped item. |
| 149 </p> |
| 150 |
| 151 <pre> |
| 152 var dnd = new DnDFileController('body', function(data) { |
| 153 var fileEntry = data.items[0].webkitGetAsEntry(); |
| 154 displayPath(fileEntry); |
| 155 }); |
| 156 </pre> |
| 157 |
| 158 <h2 id="read">Reading a file</h2> |
| 159 |
| 160 <p> |
| 161 The following code opens the file (read-only) and |
| 162 reads it as text using a <code>FileReader</code> object. |
| 163 If the file doesn't exist, an error is thrown. |
| 164 </p> |
| 165 |
| 166 <pre> |
| 167 var chosenFileEntry = null; |
| 168 |
| 169 chooseFileButton.addEventListener('click', function(e) { |
| 170 chrome.fileSystem.chooseFile({type: 'openFile'}, function(readOnlyEntry) { |
| 171 |
| 172 readOnlyEntry.file(function(file) { |
| 173 var reader = new FileReader(); |
| 174 |
| 175 reader.onerror = errorHandler; |
| 176 reader.onloadend = function(e) { |
| 177 console.log(e.target.result); |
| 178 }; |
| 179 |
| 180 reader.readAsText(file); |
| 181 }); |
| 182 }); |
| 183 }); |
| 184 </pre> |
| 185 |
| 186 <h2 id="write">Writing a file</h2> |
| 187 |
| 188 <p> |
| 189 The two common use-cases |
| 190 for writing a file are "Save" and "Save as". |
| 191 The following code creates a |
| 192 <code>writableFileEntry</code> |
| 193 from the read-only <code>chosenFileEntry</code> and |
| 194 writes the selected file to it. |
| 195 </p> |
| 196 |
| 197 <pre> |
| 198 chrome.fileSystem.getWritableFileEntry(chosenFileEntry, function(writableFileEn
try) { |
| 199 writableFileEntry.createWriter(function(writer) { |
| 200 writer.onerror = errorHandler; |
| 201 writer.onwriteend = callback; |
| 202 |
| 203 chosenFileEntry.file(function(file) { |
| 204 writer.write(file); |
| 205 }); |
| 206 }, errorHandler); |
| 207 }); |
| 208 </pre> |
| 209 |
| 210 <p> |
| 211 The following code creates a new file |
| 212 with "Save as" functionality and |
| 213 writes the new blob to the file |
| 214 using the <code>writer.write()</code> method. |
| 215 </p> |
| 216 |
| 217 <pre> |
| 218 chrome.fileSystem.chooseFile({type: 'saveFile'}, function(writableFileEntry) { |
| 219 writableFileEntry.createWriter(function(writer) { |
| 220 writer.onerror = errorHandler; |
| 221 writer.onwriteend = function(e) { |
| 222 console.log('write complete'); |
| 223 }; |
| 224 writer.write(new Blob(['1234567890'], {type: 'text/plain'})); |
| 225 }, errorHandler); |
| 226 }); |
| 227 </pre> |
| 228 |
| 229 <p class="backtotop"><a href="#top">Back to top</a></p> |
OLD | NEW |