local data storage for mobile apps
Post on 17-Jul-2015
186 Views
Preview:
TRANSCRIPT
Gran Sasso Science Institute
Ivano Malavolta
Local Storage
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
Local storage and file system access
There are 4 ways to store data locally in Cordova:
• Web storage
• Local Storage
• Session Storage
• WebSQL
• Indexed DB
• File System Access
Web storage, WebSQL, and IndexedDB conform to W3C specifications and are provided by the browser itself
File system access API conforms to its corresponding W3C specification
Web Storage
LocalStorage
stores data in key/value pairs
persists across browser sessions
SessionStorage
stores data in key/value pairs
data is erased when a browser session ends
WebSQL
relational DB
support for tables creation, insert, update, …
transactional
persists across browser sessions
WebSQL
It provides you a structured SQL relational database
You have to setup a DB schema
You can then perform classical SQL queries
tx.executeSql(‘SELECT * FROM User’, [], function(tx, result) { // callback code });
IndexedDB
• It combines Web Storage and WebSQL
• You can save data as key/value pairs
• You can define multiple DBs
• Good Performance
– data is indexed
– Asynchronous à it does not block the UI
You can see a store as a big SQL table with only key/value pairs
à you don’t need to define a schema upfront
File System
• you can access files locally to your app
• supports main FS operation– creation, move, delete, rename, etc.
• it is not transactional
• persists across browser sessions
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
Web Storage
It is based on a single persistent object called localStorage
You can set values by callingwindow.localStorage.setItem(“name”, “Ivano”);
You can get values back by calling var name = window.localStorage.getItem(“name”);
Supported Methods
.key(0) Returns the name of the key at the position specified
.getItem(“key”) Returns the item identified by it's key
.setItem(“key”, “value”) Saves and item at the key provided
.removeItem(“key”) Removes the item identified by it's key
.clear() Removes all the key-value pairs
Complex Objects
Current implementations support only string-to-string mappings
à you can store only strings
à keys can be only strings
You can use JSON serialization if you need to store complex data structures
Example of JSON Serialization
// simple class declaration function Person(name, surname) { this.name = name; this.surname = surname;
} // object creation var user = new Person(‘Ivano’, ‘Malavolta’); // object serialization window.localStorage.setItem(“user”, JSON.stringify(user)); // object retrieval var current =
JSON.parse(window.localStorage.getItem(“user”));
Checking Existence
You can simply check if the needed element is == null
if (window.localStorage.getItem(“user”)) {
// there is an object in user
} else { // the user key does not have any value
}
Selecting elements
In this case you have to manually iterate on elements
var users = [...]; // array of Person objects window.localStorage.setItem(“users”,
JSON.stringify(users)); var allUsers =
JSON.parse(window.localStorage.getItem(“users”)); var ivanos = []; for(var i=0; i<allUsers.length; i++) { if(allUsers[i].name == ‘Ivano’) ivanos.push(allUsers[i]);
}
Counting Elements
Also in this case, we have to do it manually
var usersNumber =
JSON.parse(window.localStorage.getItem(“users“)).length;
Session Storage
Session Storage provides the same interface as Local Storage
à you can call the same methods
but
Session Storage is cleared between app launches
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
WebSQL
It provides you a structured SQL relational database
You have to setup a DB schema
You can then perform classical SQL queries
tx.executeSql("SELECT * FROM User“, [],
function(tx, result) { // callback code });
Opening a DB
Done via a dedicated function
var db = openDatabase(‘Test', ‘1.0', ‘Test DB', 100000);
It creates a new SQLite DB and returns a new Database object
The Database object will be used to manipulate the data
Opening a DB: syntax
openDatabase(name, version, displayname, size);
namethe name of the DB
versionthe version of the DB
displaynamethe display name of the DB
sizethe size of the DB in bytes
Database
It allows to manipulate the data via 2 methods:
changeVersion
atomically verify the version number and change it
db.changeVersion("1.0", "1.1");
transaction
performs a DB transaction
Transactions
It allow you to execute SQL statements against the DB
db.transaction(queries, error, success);
3 functions as parameters:
queries : contains the queries to be performed
error : executed if the transaction results in an error
success : executed if the transaction terminates correctly
Transaction Example
http://bit.ly/JlUJde
executeSql
It is the method that performs a SQL statement
The user can build up a database transaction by calling the executeSql method multiple times
function populateDB(tx) { tx.executeSql('DROP TABLE IF EXISTS USER'); tx.executeSql('CREATE TABLE IF NOT EXISTS USER (id
unique, name, surname)');
tx.executeSql('INSERT INTO USER(id, name, surname) VALUES (1, ?, ?)‘, [“Ivano“, “Malavolta“], success, error);
}
Result Sets
When the executeSql method is called, it will invoke it's callback with a SQLResultSet parameter
It has 3 properties:
insertId
the ID of the row that has been inserted
rowsAffected
the number of rows changed by the SQL statement
rows
the data returned from a SQL select statement
rows is an object of type SQLResultSetList
Results Sets Example
... tx.executeSql('INSERT INTO USER(id, name,surname) VALUES (5, ?, ?)‘, [“Ivano“, “Malavolta“], success, error);
}
function success(tx, results) {
var affected = results.rowsAffected(); // 1
}
function error(err) {
// code for managing the error
}
Result Set Lists
It contains the data returned from a SQL Select statement
length the number of rows returned by the SQL query
item(index) returns the row at the specified index represented by a JavaScript object
Result Set List Example
... tx.executeSql(‘SELECT * FROM USER‘, [], success, error);
}
function success(tx, results) {
var size = results.rows.length; for (var i=0; i<size; i++){
console.log(results.rows.item(i).name); }
}
Errors
It contains information about an occurred error
code
A predefined error code
es. UNKNOWN_ERR,
DATABASE_ERR,
TOO_LARGE_ERR,
QUOTA_ERR,
TIMEOUT_ERR,
SYNTAX_ERR
messageA description of the error
error not considered by any other error codes
internal error of the database
the result set is too large
the db now exceeds the storage space of the app
• the statement is not sintactically correct• the number of parameters does not match with
placeholders
no reasonable time to get the lock for the transition
Error Code Example
...
tx.executeSql(‘SELECT * FROM USER‘,[], success, error); }
function error(err) { console.log(err.code);
}
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
Indexed DB
It tries to combine Web Storage and WebSQL
You can save data as key/value pairs
You can define multiple DBs
Good Performance
data is indexed
asynchronous à it does not block the UI
Indexed DB
An Indexed DB is a collection of object stores
You can drop objects into the stores
You can see a store as a big SQL table with only key/value pairs
à you don’t need to define a schema upfront
IndexedDB !== mobile storage
still not fully supported by iOS
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
File System Access
It allows you to read, write and navigate file system hierarchies
It is fundamental for managing and storing large files and binary content on the client-side
File System Access Workflow
1. request file system access– persistent or temporary file system
2. then you can perform CRUD operations for both files and folders:– Create
– Read
– Update
– Delete
Request File System
requestFileSystem(type, size, successCb, [errorCb])
type
LocalFileSystem.TEMPORARYLocalFileSystem .PERSISTENT
sizesize in bytes the app will require for storage
successCbsuccess callback, its argument is a FileSystem object
ErrorCberror callback, its argument is a FileError object
Temporary VS Persistent
Temporary
the files stored by the app can be deleted at the browser’s discretion
à no guarantee of persistence
Persistent
cannot be deleted by the browser without authorization by the app
Local File System Example
window.requestFileSystem( LocalFileSystem.PERSISTENT,
0, onSuccess,
onError);
function onSuccess(fileSystem) {
console.log(fileSystem.name);
}
leave it to zero, Apache Cordova will take care of it
File System
The FileSystem object has 2 properties:
name
the name of the file system
it is unique across the list of exposed file systems
root
the DirectoryEntry object representing the root folder of the file system
Resolving a File URI
window.resolveLocalFileSystemURI
retrieve a DirectoryEntry or FileEntry using a URI
window.resolveLocalFileSystemURI(
"file:///userImg.png", onSuccess, onError);
function onSuccess(fileEntry) { console.log(fileEntry.name);
}
Important directories
Entities
FileEntry
DirectoryEntry
File
FileReader
FileWriter
DirectoryReader
The real objects
Descriptor
Writing & Reading objects
File Entry
It represents a file on a file system
isFile (boolean)
Always true
isDirectory (boolean)
Always false
name (DOMString)
the name of the FileEntry, excluding the path
fullPath (DOMString)
the full absolute path from the root
File Entry Methods
getMetadata(success, fail) Look up metadata about a file
setMetadata(success, fail, metadataObject) Sets the metadata of the file
moveTo(parentEntry, newName, success, fail)Move a file to a different location on the file system
copyTo(parentEntry, newName, success, fail)Copy a file to a different location on the file system
toURL()Return a URL that can be used to locate a file
File Entry Methods
remove(success, fail)
Delete a file
getParent(success, fail)
Look up the parent directory
createWriter(success, fail)
Creates a FileWriter object that can be used to write to a file
file(success, fail)
Creates a File object containing file properties
File
It contains attributes of a single file
name (DOMString)
The name of the file
fullPath (DOMString)
The full path of the file including the file name
type (DOMString)
The mime type of the file
lastModifiedDate (Date)
The last time the file was modified
size (long)
The size of the file in bytes
Directory Entry
It represents a directory on a file system
It has the same properties of FileEntry
Directory Entry Methods
getMetadata(success, fail) Look up metadata about a directory
setMetadata(success, fail, metadataObject) Sets the metadata of the directory
moveTo(parentEntry, newName, success, fail)Move a directory to a different location on the file system
copyTo(parentEntry, newName, success, fail)Copy a directory to a different location on the file system
toURL()Return a URL that can be used to locate a directory
Directory Entry Methods
getParent(success, fail)Look up the parent directory
createReader()Creates a DirectoryReader object that can be used to read a directory
getDirectory(path, options, success, fail)Creates or looks up a directoryoptions: create: (true | false)exclusive: (true | false)
Directory Entry Methods
getFile(path, options, success, fail)
Create or look up a file within the directory
options are used when the file does not exist:
create à (true | false)
exclusive à (true | false)
removeRecursively(success, fail)
Delete a directory and all of its contents
File Reader
It is used to read the contents of a file
Files can be read as:
• text
• base64 data encoded string
• binary string
• array buffer
You can also abort() a file reading activity
You can register your own event listeners to receive the following events:loadstart, progress, load, loadend, error, abort
File Reader Example
entry.file(win, fail);
function win(file) {
var reader = new FileReader(); reader.onloadend = function(evt) {
console.log(evt.target.result); }; reader.readAsText(file);
// reader.abort(); };
function fail(evt) { console.log(error.code);
};
File Writer
It is used to write to a file
The data to be written must be UTF-8 encoded
You can register your own event listeners to receive the following events:
writestart, progress, write, writeend, error, abort
File Writer
A FileWriter is created for a single file
You can use it to write to a file multiple times
à the FileWriter maintains the file's position and length attributes, so you can seek and write anywhere in the file
By default, the FileWriter writes to the beginning of the file (will overwrite existing data)
Set the optional append boolean to true in the FileWriter's constructor to begin writing to the end of the file
File Writer Methods
abort()
Aborts writing file
seek(byte)
Moves the file pointer to the byte specified.
truncate(length)
Shortens the file to the length specified.
write(data)
Writes data to the file
File Writer Example
entry.createWriter(win, fail);
function win(writer) {
writer.onwrite = function(evt) { console.log(“ok");
}; writer.write(“Ivano Malavolta");
};
function fail(evt) { // error management
};
Directory Reader
It is an object that lists files and directories in a directory
It has only one method:
readEntries(success, fail)
Read the entries of the directory
Directory Reader Example
var directoryReader = dirEntry.createReader(); directoryReader.readEntries(success, fail);
function success(entries) {
var i; for (i=0; i<entries.length; i++) { console.log(entries[i].name); }
}
function fail(error) {
console.log(error.code);
}
A Final Example
window.requestFileSystem(window.PERSISTENT, 0, initFS, error); function initFS(fs) { fs.root.getFile(‘log.txt', {}, win, error); } function win(fileEntry) { fileEntry.file(read, error); } function read(file) { var reader = new FileReader();
reader.onloadend = function(e) { console.log(this.result); }; reader.readAsText(file);
} function error(err) { console.log(err);}
Looking for a file and reading it
File upload
Upload files to a remote server via an HTTP multi-part POST request
var fileURI; // the path of the file on the device
var server; // encoded URL of the server var win; // success callback
var fail; // error callback
var options; // optional parameters (see next slide)
var trustAllHosts; // optional boolean parameter, // true to accept all security certificates
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI(server), win, fail, options);
File upload options
The FileUploadOptions can be used to specify additional parameters to the upload script
var options = new FileUploadOptions();
options.fileKey="file”;
options.fileName= “fileName”);
options.mimeType="text/plain";
…
File upload options
File upload result
A FileUploadResult object is passed to the success callback
Properties:
bytesSent: the number of bytes sent to the server
responseCode: The HTTP response code returned by the server
response: The HTTP response returned by the server as string
headers: the headers of the HTTP response by the server
not supported in iOS
not supported in iOS
File download
Downloads files from a remote server via an HTTP GET request
var source; // URL of the file to be downloaded
var target; // full path of the file to be saved var win; // success callback (takes FileEntry object) var fail; // error callback
var options; // optional parameters (only headers)
var trustAllHosts; // optional boolean parameter, // true to accept all security certificates
var ft = new FileTransfer();
ft.download(encodeURI(source),target, win, fail, options);
File transfer abort
Used to stop an on-going file transfer
var ft = new FileTransfer(); ft.upload(fileURI, encodeURI(server), win, fail, options); // perform some operation ft.abort():
File transfer progress
Special callback activated every time a new piece of data is
transferred
ft.onprogress = function(progress) { if (progressEvent.lengthComputable) { console.log((progress.loaded / progress.total) + “%”); } else { console.log(“progressed”); } }; ft.download(...); // the same works for upload
File transfer error
The FileTransferError object stores information about an error
occurred during a file transfer (either upload or download)
Properties:
code: predefined error code
source: URI of the source
target: URI of the target
http_status: HTTP status code from the server (if received)
FileTransferError.FILE_NOT_FOUND_ERRFileTransferError.INVALID_URL_ERRFileTransferError.CONNECTION_ERRFileTransferError.ABORT_ERR
Roadmap
Introduction
Web Storage
WebSQL
IndexedDB
File System Access
Final Considerations
Considerations
You will likely use more than one API in combination
à Use the right API for the right job
Web Storage
• it is not transactional à race conditions
• very simple API, no schema
• only String data à performance issues for complex data due to JSON serialization
• session storage will be cleared after the app is closed
• limited quota
Considerations
WebSQL
SQL-based à fast and efficient
transactional à more robust
asynchronous à does not block the UI
rigid data structure à data integrity vs agility
limited quota
Considerations
IndexedDB
simple data model à easy to use
transactional à more robust
asynchronous à does not block the UI
good search performance à indexed data
data is unstructured à integrity problems
limited quota
not fully supported by every platform (e.g., iOS)
Considerations
File System
asynchronous à does not block the UI
not transactional
indexing and search are not built-in à you have to implement your lookup functions
unlimited quota à useful for images, videos, documents, etc.
Platforms support
About quotas...
Local Storage
~ 10Mb
Session Storage
~ 10Mb
WebSQL
~ 50-80Mb (depends on the device)
Indexed DB
~ 50-80Mb (depends on the device)
File system
unlimited
Native DB
unlimited
Exercises
Extend the previous exercises you developed about Frascati events so that users can:
1. save a specific event or “ente” as favorited via local storage
2. define a dedicated “Favorites” view of the app;
3. define a WebSQL DB for storing events and “enti”;– here you can support a very limited subset of the data
4. define a data prefetcher that at the first launch of the app saves all the data coming from the Rest API to the WEBSQL database;– in the subsequent launches of the app, the data must come from
the WebSQL database, and not from the Rest API
Data:http://www.ivanomalavolta.com/files/data/frascatiEventi.jsonhttp://www.ivanomalavolta.com/files/data/frascatiEnti.json
References
http://cordova.apache.org/docs/en/edge
ContactIvano Malavolta |
Gran Sasso Science Institute
iivanoo
ivano.malavolta@gssi.infn.it
www.ivanomalavolta.com
top related