Requirements:
- RequireJS based cordova project
- (jQuery's) Deferred function (or other code that provides "deferred" functionality)
- jQuery's JSON Plugin (or alternative JSON serializer)
- Phonegap File access permissions
define(["jquery", "utils", "cordova"], function($, utils, cordova) {
"use strict";
/**
* Filename to store data in
*/
var fileName = "myproject.db"
/**
* Store cache object
* (the app reads from here to avoid unnecessary file accesses)
*/
var store = {};
/**
* Is the module initialized, see isReady() method.
*/
var status = $.Deferred();
/**
* Common error handler
* @param error
*/
function fail(error) {
status.resolve();
utils.log(error, 'Error in Storage!');
}
/**
* Get file entry for the fileName
* (if not existing the file is created)
* @param callback where the fileEntry is used
*/
function getFileEntry(callback) {
var options = {create : true,
exclusive : false};
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem) {
fileSystem.root.getFile(fileName, options, function(fe) {
callback(fe);
});
}, fail);
}
return {
/**
* Check if the storage is ready to use.
*/
isReady : function() {
return status;
},
/**
* Initiates the storage module for usage
* (for local development in a browser,
* HTML5's localStorage is used)
*/
init : function() {
if (!utils.isBrowserMode()) {
getFileEntry(function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onload = function(evt) {
if (evt && evt.target && evt.target.result) {
// Just a little debug output
// to see the file content
utils.log(evt.target.result, 'Settings');
// readed JSON is set on local cache obj
store = $.evalJSON(evt.target.result);
} else {
utils.log(evt, 'read error ' + fileEntry.fullPath,
'Error loading from device.');
}
// if finished then resolve the deferred command
status.resolve();
};
// Error handling
reader.onerror = function(err) {
utils.log(err, 'Storage reading error '
+ fileEntry.fullPath);
status.resolve();
};
// read the file as text
reader.readAsText(file);
});
});
} else {
utils.log({}, "Browser mode, using localStorage!");
store = localStorage;
status.resolve();
}
},
/**
* Set value
*
* @param name
* @param value
*/
set : function(name, value) {
// Set in cache
store[name] = value;
var encoded = $.toJSON(store);
// Write to file
if (!utils.isBrowserMode()) {
getFileEntry(function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.truncate(0);
writer.onwriteend = function(evt) {
// console.log("write success " + encoded);
};
writer.write(encoded);
}, fail);
});
}
},
/**
* Get value
*
* @param name
*/
get : function(name) {
var value = null;
if (store[name]) {
value = store[name];
}
return value;
}
};
});
Currently this is based on a deferred pattern, because in this case the storage has to be fully loaded before the authentication is initialized. If there is no need for synchronous waiting, also a custom event can be triggered. Just remove the deferred and isReady() and replace resolve() with triggering an event. If using jQuery:
$("body").trigger({
type:"storageready"
});
No comments:
Post a Comment