Local data storage for mobile apps

80
Gran Sasso Science Institute Ivano Malavolta Local Storage

Transcript of Local data storage for mobile apps

Page 1: Local data storage for mobile apps

Gran Sasso Science Institute

Ivano Malavolta

Local Storage

Page 2: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 3: Local data storage for mobile apps

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

Page 4: Local data storage for mobile apps

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

Page 5: Local data storage for mobile apps

WebSQL

relational DB

support for tables creation, insert, update, …

transactional

persists across browser sessions

Page 6: Local data storage for mobile apps

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  });  

Page 7: Local data storage for mobile apps

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

Page 8: Local data storage for mobile apps

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

Page 9: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 10: Local data storage for mobile apps

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”);

Page 11: Local data storage for mobile apps

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

Page 12: Local data storage for mobile apps

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

Page 13: Local data storage for mobile apps

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”));

Page 14: Local data storage for mobile apps

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

}

Page 15: Local data storage for mobile apps

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]);

}

Page 16: Local data storage for mobile apps

Counting Elements

Also in this case, we have to do it manually

var usersNumber =

JSON.parse(window.localStorage.getItem(“users“)).length;

Page 17: Local data storage for mobile apps

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

Page 18: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 19: Local data storage for mobile apps

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 });

Page 20: Local data storage for mobile apps

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

Page 21: Local data storage for mobile apps

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

Page 22: Local data storage for mobile apps

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

Page 23: Local data storage for mobile apps

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

Page 24: Local data storage for mobile apps

Transaction Example

http://bit.ly/JlUJde

Page 25: Local data storage for mobile apps

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);

}

Page 26: Local data storage for mobile apps

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 

Page 27: Local data storage for mobile apps

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

}

Page 28: Local data storage for mobile apps

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

Page 29: Local data storage for mobile apps

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); }

}

Page 30: Local data storage for mobile apps

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

Page 31: Local data storage for mobile apps

Error Code Example

...

tx.executeSql(‘SELECT * FROM USER‘,[], success, error); }

function error(err) { console.log(err.code);

}

Page 32: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 33: Local data storage for mobile apps

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

Page 34: Local data storage for mobile apps

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

Page 35: Local data storage for mobile apps

IndexedDB !== mobile storage

still not fully supported by iOS

Page 36: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 37: Local data storage for mobile apps

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

Page 38: Local data storage for mobile apps

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

Page 39: Local data storage for mobile apps

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

Page 40: Local data storage for mobile apps

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

Page 41: Local data storage for mobile apps

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

Page 42: Local data storage for mobile apps

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

Page 43: Local data storage for mobile apps

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);

}

Page 44: Local data storage for mobile apps

Important directories

Page 45: Local data storage for mobile apps

Entities

FileEntry

DirectoryEntry

File

FileReader

FileWriter

DirectoryReader

The real objects

Descriptor

Writing & Reading objects

Page 46: Local data storage for mobile apps

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

Page 47: Local data storage for mobile apps

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

Page 48: Local data storage for mobile apps

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

Page 49: Local data storage for mobile apps

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

Page 50: Local data storage for mobile apps

Directory Entry

It represents a directory on a file system

It has the same properties of FileEntry

Page 51: Local data storage for mobile apps

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

Page 52: Local data storage for mobile apps

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)

Page 53: Local data storage for mobile apps

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

Page 54: Local data storage for mobile apps

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

Page 55: Local data storage for mobile apps

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);

};

Page 56: Local data storage for mobile apps

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

Page 57: Local data storage for mobile apps

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

Page 58: Local data storage for mobile apps

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

Page 59: Local data storage for mobile apps

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

};

Page 60: Local data storage for mobile apps

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

Page 61: Local data storage for mobile apps

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);

}

Page 62: Local data storage for mobile apps

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

Page 63: Local data storage for mobile apps

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);

Page 64: Local data storage for mobile apps

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";

Page 65: Local data storage for mobile apps

File upload options

Page 66: Local data storage for mobile apps

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

Page 67: Local data storage for mobile apps

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);

Page 68: Local data storage for mobile apps

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():

Page 69: Local data storage for mobile apps

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

Page 70: Local data storage for mobile apps

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

Page 71: Local data storage for mobile apps

Roadmap

Introduction

Web Storage

WebSQL

IndexedDB

File System Access

Final Considerations

Page 72: Local data storage for mobile apps

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

Page 73: Local data storage for mobile apps

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

Page 74: Local data storage for mobile apps

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)

Page 75: Local data storage for mobile apps

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.

Page 76: Local data storage for mobile apps

Platforms support

Page 77: Local data storage for mobile apps

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

Page 78: Local data storage for mobile apps

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

Page 79: Local data storage for mobile apps

References

http://cordova.apache.org/docs/en/edge

Page 80: Local data storage for mobile apps

ContactIvano Malavolta |

Gran Sasso Science Institute

iivanoo

[email protected]

www.ivanomalavolta.com