How permanent is local storage on Android and iOS?

When my app stores data locally on a phone, how permanent is that storage? I'll elaborate the exact situation:

I'm building an app with jQueryMobile and Phonegap. It's essentially a browser app, but using Phonegap lets me package it and sell it in the app stores, among other advantages.

Phonegap offers two ways of storage, both of which functions harmonize native functions of iOs, Android, Blackberry and some other OSs: localStorage (which is primitive key-value pairs), and a Web SQL database. Both localStorage and web SQL are forms of storage that belong to the browser. Having said that, I can't find out how long the data will stay stored, under what circumstances it will be deleted, under what circumstances it may not be available, etc.

For example, if the app stores data with localStorage or web SQL, and the user switches to a different standard browser on their Android, will the app be opened with the new browser and does that mean that the stored data is unavailable?

If the user doesn't use the app for a year (which in my case is a realistic and not necessarily a bad scenario), will the data have expired like a cookie, or maybe been pushed out of the browser's storage by a deluge of data from other apps?

Or will the data be destroyed even earlier, such as when: - user visits another site in the browser - browser is manually closed - browser process is killed or dies - etc

Or are localStorage and web SQL the kind of storage that you only delete when (in Android) you go to Settings > Apps and actively remove the user data associated with the app?

Thanks for any insights. There's nothing informative out there on ol' WWW.

What happens in the case of app update. The local and web storage will get deleted or will it stay?

46359 次浏览

Let me answer step by step

if the app stores data with localStorage or web SQL, and the user switches to a different standard browser on their Android, will the app be opened with the new browser and does that mean that the stored data is unavailable?

The data is saved in the 'cache'(its not exactly the cache) of the browser, so if you change the browser, or set the settings so that the default browser is removed or changed, the data will go.

If the user doesn't use the app for a year (which in my case is a realistic and not necessarily a bad scenario), will the data have expired like a cookie, or maybe been pushed out of the browser's storage by a deluge of data from other apps?

No, the data will stay there no matter for how long it is not used. So even if you clear the browser cache, it will still be there.

Or will the data be destroyed even earlier, such as when: - user visits another site in the browser - browser is manually closed - browser process is killed or dies - etc

No, the data stays all right. :-)

Or are localStorage and web SQL the kind of storage that you only delete when (in Android) you go to Settings > Apps and actively remove the user data associated with the app?

Yes, the data only goes if you either manually delete it from your app or you uninstall your app. It will stay in all other cases.

EDIT: In the case of iOS, the OS will remove the data in the local storage when there is a shortage of memory in the device.

As of iOS 5.1 @ghostCoder's answer is no longer valid. Apple has decided to move the localstorage location into a cache folder which can be emptied anytime. You can track this discussion here:

Google Groups Discussion on Localstorage

Also this blog explains the problem in more detail:

http://www.marco.org/2011/10/13/ios5-caches-cleaning

It is possible to manually point your localstorage location to a safe Application_Home>/Documents location. To determine your current localstorage location you can use something like this:

NSString* localStorageSubdir = (IsAtLeastiOSVersion(@"5.1")) ? @"Caches" : @"WebKit/LocalStorage";
NSString* localStoragePath = [library stringByAppendingPathComponent:localStorageSubdir];
NSString* localStorageDb = [localStoragePath stringByAppendingPathComponent:@"file__0.localstorage"];

The following code allows you to set another location for your localstorage:

NSString* bundleIdentifier = [[mainBundle infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSString* libraryPreferences = @"Library/Preferences";
NSString* appPlistPath = [[bundlePath stringByAppendingPathComponent:libraryPreferences]    stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", bundleIdentifier]];


NSString *value;
NSString *key = @"WebKitLocalStorageDatabasePathPreferenceKey";
value = [appPlistDict objectForKey: key];
if (![value isEqual:ourLocalStoragePath]) {
[appPlistDict setValue:yourPreferredLocalStoragePath forKey:key];
}

I can't speak for other platforms, but on my 4.1 Android device, I'm using localStorage to store some data locally with jQuery Mobile, and I've found that Android will clear my cache every week or so without my knowledge. I'm going to give Web SQL a try and see if that's better.

I found this online ng-persist

Store data on mobile devices (using cordova) that persists even if the user reinstalls the app

Install

bower install ng-persist ngstorage --save

Inject $persist into your controller

.controller('MyCtrl', function($persist) {


$persist
.set(namespace, key, val)
.then(function () {
// saved
});


// read
$persist
.get(namespace, key, fallback)
.then(function (val) {
// val is either the value, if exists, or the fallback
});


// delete
$persist
.remove(namespace, key)
.then(function () {
// removed
});


});

On android it's a permanent storage by default. Even if the user updates your app it stays the same.

The user can go to settings and clear cache and data in which case it goes or if say one of the clean-it apps does it.

Even on iOS it's permanent storage but don't know about app update scenario. But in older version(5.1) it wasn't and in 6+ they made that it can be made permanent through a flag which was promptly enabled by cordova/phonegap.

Try the NativeStorage plugin. https://www.npmjs.com/package/cordova-plugin-nativestorage.

It has set, put and get functions which implement platform capabilities like android shared preferences and iOS NSUserDefaults which makes data store as safe as allowed.

cordova plugin add cordova-plugin-nativestorage


NativeStorage.putObject("reference_to_value",<object>, <success-callback>, <error-callback>);


NativeStorage.getObject("reference_to_value",<success-callback>, <error-callback>);

A good solution which is available now is The Cordova Native Storage Plugin.

It allows a simple yet native persistant method to save data in iOS and Android by natively implementing SharedPreferences in Android and NSDefault in iOS to guarantee reliability.

Usage:

Installation:

cordova plugin add cordova-plugin-nativestorage

Storing values:

NativeStorage.setItem("reference_to_value",<value>,<success-callback>, <error-callback>);

Retrieving values:

NativeStorage.getItem("reference_to_value",<success-callback>, <error-callback>);

It would be better in terms of performance, security and reliability to AVOID using local storage and use Cordova-sqlite-storage instead.

Some notes:

localStorage has the advantage of being easy to use, but it works in a synchronous way. This means that it can lock the UI thread and cause slow performance.

localStorage has a limited amount of storage, usually its 5mb.

localStorage can be wiped out by the OS (android,ios) at any time. This is really serious if you care about data persistance.

On the other hand:

Cordova-sqlite-storage is asynchronous and it will not block the UI thread, it saves your data on the native device storage, the amount of storage is not limited, the OS will not delete any of your data, unless you uninstall the app.