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