iOS 7 webview and localStorage persistence - ios

I'm developing a hybrid app (for iOS and Android only) using PhoneGap/Cordova and want to use HTML5 localStorage to store content for offline access.
http://caniuse.com/#search=localStorage says - "In iOS 5 & 6 localStorage data is stored in a location that may occasionally be cleared out by the OS."
What is the situation with an iOS 7 (and later) webview, in what cases will localStorage persist, or get cleared out (by the OS, or the user)?
Will an update to the app clear localStorage?
What about the user clearing browser history on Safari - will that apply to the webview too?
Do I need to worry (or can I even control) where on the fils system the localStorage is created. I understand it should not be backed up on iCloud.
I got a device (iPad) and checking the file system I see that localStorage file is in ~/Library/Caches within the app sandbox, see image below.
From the docs:
https://developer.apple.com/icloud/documentation/data-storage/index.html
Data that can be downloaded again or regenerated should be stored in the /Library/Caches directory. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications.
I am simply doing this to set data:
localStorage.setItem('foo','this is the FOO value');
localStorage.setItem('bar','and this is the BAR value');

If you do still face the issue with Cordova-iOS v4 , then 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>);

If you are using cordova, that problem was fixed long time ago, even for iOS 5 and iOS 6. You shouldn't worry if you are using the latest version of cordova.

Your best bet is to use the NativeStorage plugin:
https://www.npmjs.com/package/cordova-plugin-nativestorage
To answer your questions:
The localStorage data is kept in a cache directory in the filesystem, and cache is cleaned by the OS frequently (for example when the device is low on disk space).
No, updating the app won't clear local storage.
No, Safari local storage and Webview local storage are separate.
No, you cannot control where on the filesystem it's stored.

Related

Offload App remove what in iOS 11

I just installed iOS 11 beta and I noticed that Offload App, By offloading app what will be remove Shared Directory or User Default or remove both or other than this ?
Looking for suggestions.
Thanks
Offloading lets you ”offload” the bundle (.ipa) for your app to save disk space. It will delete the ipa file (which contains your libraries and resources) and store only Documents and Data that includes shared data, UserDefaults etc..
Once we offload the app, what remains is the app icon of it with a small download pip on it to indicate that it has been offloaded .
Just by simple tapping on it, the app will get downloaded from the store and the saved Documents and Data will be integrated to the downloaded app, instead of an empty directory as it normally would with a fresh install.
This is a really great feature by Apple especially for devices with just 16GB storage. As you can see offloading the Prisma app saves me 44MB which is great. And even more, iOS can automatically offloads unused apps for us.
There is no official document(technical) available for offloading apps till the date but as the description(in setting app) says that your documents and data will be saved then I think it will save user defaults , document directories and core data - I mean all kind of data that can be stored!
It will save Shared Directory & User Defaults. Everything else will be deleted.

Persist localstorage in cordova app when app updates via app store

I have a iOS app built using Ionic (Cordova and Angular). Version 1 of my app (which has been released for a while) stores some data using HTML5 localStorage. I'm ready to release version 2 but updating the app (I've simulated both via xcode, itunes and via a testflight install) wipes all the data stored in localstorage.
It seems the localstorage db is stored in Library/Caches/ if that is helpful.
For info I'm using:
Cordova 3.9.2 and Ionic 1.1.1
After spending all day searching SO and various other sites I'm still no wiser.
Is there a way to prevent this? Interested to hear from anyone using localStorage on a released cordova app.
As you mentioned the localstorage is stored in Library/Caches. This directory may get cleared by the OS if the system is very low on space (File System Programming Guide).
If the system isn't low on space the data should be available after app updates. We are using localstorage in our app too and having problems with loosing data when the device runs out of space.
After researching I've found a plugin especially for this problem. This plugin is using NSUserDefaults (iOS) and SharedPreferences (Android) to store the data permanently. This is actually my preferred solution for this problem.
I have used the Cordova SQL Lite plugin which persists to the app's data directory on this disk. This data persists when the app is updated. This is your best bet today since it works well on iOS and Android.
This plugin is also saves data using NSUserDefaults (iOS) and SharedPreferences (Android) to store the data permanently.

Are NSPersistentDocument and UIManagedDocument compatible?

I would like to create a NSPersistentDocument in Mac OS X and read this document as a UIManagedDocument on iOS 7.
Is this possible?
Are both file formats compatible?
Thank you!
Interesting question - I can confirm that the basic core data files are compatible. I have a Mac app and an iOS app using the same file that gets synced using iCloud. The app is a document based app and currently I have been storing the actual database file in iCloud so the whole file gets sync'ed by iCloud.
This works fine but obviously if a user opens the file on two devices and is not careful about saving and closing there is a possibility their changes may be overridden.
Apple has approved the Mac app which uses standard NSPersistentDocument to create and save files. Unfortunately they have rejected the iOS apps with some obscure reference to not conforming to their data storage guidelines, saying that documents must be stored in /Documents directory if they need to be backed up to iCloud. Well if the user has selected iCloud then I store the files in the iCloud location provided by the API calls.
Anyway I am still waiting to hear back from them about what is specifically wrong with this approach since it seems to be the same one used by Pages and other document based apps.
If I try using UIManagedDocument then iOS creates a folder structure and stores the database inside this folder structure. The Mac app File->Open dialog then shows this folder structure as well as a file that essentially looks like a the normal sqlite file. But then perhaps OS X 10.8.4 does not implement the latest iCloud/Core Data stuff - who knows...
EDIT
Here is a link to code examples and videos showing OSX and iOS app integration using Core Data and iCloud. http://ossh.com.au/design-and-technology/software-development/uimanageddocument-icloud-integration/
I agree this is definitely possible. I'm using NSPersistent document on OS X 10.8/10.9/10.10 with a binary core data format (no wrappers - plain files). On iOS i'm using UIDocument. Core data works fine in both environments.
Apple says NSPersistentDocument does not support iCloud. It is more correct to say it isn't fully supported. Most of the NSDocument support (which includes iCloud Document Library access from 10.8) will work. Handling of conflicted files on open works.
You can't enable auto save (which is listed as a requirement for iCloud Documents in the iCloud Design Guide). Autosave works asynchronously and is definitely not supported by NSPersistentDocument.
So if you handle file saving, and conflicts, it is possible to use NSPersistent document. There are some quirks: so, for example, if an iCloud change arrives on OS X for a document that is open, the normal NSDocument response would be to automatically reopen the document. This doesn't happen - and there is no warning the file has changed until you are about to save the file. But at least there is a warning. On iOS it is easier to detect changes as they happen by using UIDocumentStateChangedNotification.

iOS Clears HTML5 Offline Cached Data

We developed an offline HTML5 web-app using the .manifest caching mechanism. Everything works as expectet.
Now some of our customers complain that after a long period of offline usage the cached data suddenly disappeared. It turns out - this is my guess - that iOS stores the cached files in its /CACHES/ directory, which, since iOS 5.0, can get purged if the device gets out of space. This can happen anytime, without even a warning to the user. Hence, the offline webapp is no longer running properly. The user has to reconnect the device to the internet and update the app.
For native Apps this problem is solved by storing the files in the /DOCUMENTS/ dir, using the flag 'do not backup' which prevents the files from being purged (since they don't sit in the /CACHES/ dir, and are not backed up to iCloud or iTunes.
See this link for details: http://www.marco.org/2011/10/13/ios5-caches-cleaning, however this does not say anything about HTML5 caching...
This one explains it again, however no solution: http://www.moneytoolkit.com/2012/04/apple-ios-html5-localstorage-is-broken/
Has anyone experienced the same? Is there a solution to this? The goal is to install a web-app once, and then run it without connection 'forever'...
Cheers, pawi
There is no way around this in Safari. A cache is never considered to be permanent.
If you have a UIWebView inside a native app, you can set WebKitStoreWebDataForBackup to YES in your user defaults. (iOS 6+ only)

How to stop the HTML 5 database from being deleted, when using Phonegap and iOS 5.1

I am creating a quiz style app for iOS using phonegap. The app allows users to create then take the quizzes.
Currently I am using a HTML 5 database using phonegap APIs to store the test and results data. I am concerned though that the database can now be deleted by iOS 5.1 when the device storage gets full.
Is there anyway to mark the webkit cache folder where the database is stored so that it is never deleted? If this is not possible are there any suggestions for another way to store data that will always be persistent.
Yes, it's a pity that Apple did that in iOS5.1
It's possible to change the location of WebKit data calling a private API. You should be able to set the location to a secure folder like Documents. I did not test this solution yet, but look at this post : How do I enable Local Storage in my WebKit-based application?
Phonegap team is also working on that problem: https://issues.apache.org/jira/browse/CB-330
Antoher way is to use SQLite (same as WebSQL) with a phonegap plugin. That plugin save the database in the Document folder, that mean that the DB is not deleted and is saved by iCloud.
Here is the Native SQLite phonegap plugin : https://github.com/davibe/Phonegap-SQLitePlugin
Regarding this plugin, it's a little but slower than WebSQL in some case, and there are some differences between the WebSQL API, but here is an adaptor:
https://gist.github.com/2009518
You should also migrate the old WebSQL db file (stored in Library/WebKit or Caches directory) to the Document folder. Here is a code to do that :
https://gist.github.com/2009491
And if the data are important, you should save it to a server. I wrote a small lib to synchronize the SQlite DB to a server :
https://github.com/orbitaloop/WebSqlSync
There is a fix for both issues with Webkit storage and iOS 5.1
Storage moved from /Webkit to /Cache
Storage is not adjusted to updated folder structure on an App update under iOS 5.1 (WebKit Bug)
https://issues.apache.org/jira/browse/CB-330
This solution seems to be more safe than just changing the location of Webkit data calling a private API. While the App is running the Webkit storage locations are used. On resuming or terminating all data is backuped to the documents folder. Timestamps ensure that ab old backup cannot overwrite newer storage data (if the app crashes...).
The best: Users that are on an older iOS Version using an App with that fix in it, will not suffer damage lost in case of any iOS updates. Thats why one should not wait...
Instead of using an html5 database, I would send/receive the data via ajax (on a remote server, with php and mysql), preferably encrypted (and base64_encoded).

Resources