Dealing with Quotas in WebSQL on iPhone

This post details various scenarios related to the user being prompted for more storage by the browser. You as a developer must handle these to avoid data loss. Some solutions are presented.

In this post I specify Safari, but that is only because I have tested this solely on that platform. It probably applies to most mobile webkit browsers.

Specifying data store size

If you specify a size >= 5MB in Safari (iOS),  the user will be prompted for an increase in storage. Refusing to do so will throw an exception

Error: SECURITY_ERR: DOM Exception 18)

Specifying any size < 5MB will let you enter up to 5MB of data, regardless of what you specified as the size when you created the database.

Where the fun begins …

Once the user inserts data that exceeds the quota set, she will be prompted to increase the size. The Safari Database Guide mandates (in the section on ‘Error codes) that in the case of the user turning the proposal down (not increasing size), the error callback should be called with an SqlError with error code 4. This does not happen for the callback specified for the executeSql method.Note the underlined text.

If neither of the specified callbacks are called, then how do I find out that the user was prompted to increase the size on an INSERT? My mind was in total disarray until I realized that transaction method takes callbacks!

From the specification on the Asynchronous Database API

void transaction(in SQLTransactionCallback callback, in optional SQLTransactionErrorCallback errorCallback, in optional SQLVoidCallback successCallback);

No example code showed this, and so I kept on assuming it did not.

So instead of writing

db.transaction(function (tx) {
// if this prompts the user to increase the size it will not execute the sql or run any of the callbacks
tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')', onComplete, onError );
});

Do this

// Note the reverse order of the callbacks!
db.transaction(function (tx) {
// this will prompt the user to increase the size and the sql will not be executed
tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')');
}, onError, onComplete );

Conclusion

AFAIK, there are two ways of dealing with prompts for more space.

1. Try to avoid them as much as possible by setting the size of the database at the start of your program, catching any exceptions there. In order to avoid further prompts you have to manually monitor space usage to know when you are close to your maximum limit, so as to prevent further storage.

2. Wrap all write operations in a transaction where you monitor whether the transaction failed or not. If you catch Error code 4, then inform the user that your application needs more space in order to work, and force a reprompt.

Legg igjen en kommentar

Fyll inn i feltene under, eller klikk på et ikon for å logge inn:

WordPress.com-logo

Du kommenterer med bruk av din WordPress.com konto. Logg ut / Endre )

Twitter picture

Du kommenterer med bruk av din Twitter konto. Logg ut / Endre )

Facebookbilde

Du kommenterer med bruk av din Facebook konto. Logg ut / Endre )

Google+ photo

Du kommenterer med bruk av din Google+ konto. Logg ut / Endre )

Kobler til %s

%d bloggers like this: