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