简体   繁体   中英

localStorage setItem doesn't work on ipad

In my hydbrid app (Phonegap), I am trying to write to localStorage in a very standard way :

window.localStorage.setItem("proDB", JSON.stringify(data));

or

window.localStorage["proDB"] = JSON.stringify(data);

But it doesn't work on Safari on iPad 2 (iOS 7.1).

It doesn't work and the whole app stops.

Here's the userAgent of this ipad : 在此输入图像描述

Can you help me ?

Thanks

Please check whether you have Private Browsing enabled in Safari. In Safari Private Browsing mode, you get a quota of zero. Hence, all calls to localStorage.setItem will throw a quota exceeded error. Personally I think this is a huge mistake by Safari (as so many sites break), but it is what it is so we have to find a way around it. We can do this by:

  1. Detecting whether we have a functional localStorage
  2. Falling back to some replacement if not.

Read on if you want the details :)

1: Detecting a functional local storage

I am currently using this code to detect whether local storage is available, and fall back to a shim if not:

var DB;
try {
  var x = '_localstorage_test_' + Date.now();
  localStorage.setItem(x, x);
  var y = localStorage.getItem(x);
  localStorage.removeItem(x);
  if (x !== y) {throw new Error();} // check we get back what we stored
  DB = localStorage; // all fine
}
catch(e) {
  // no localstorage available, use shim
  DB = new MemoryStorage('my-app');
}

EDIT: Since writing this I have packaged up the feature detecting code. If you are using NPM you can install storage-available like so:

npm install --save storage-available

then you can use it in your code like this:

if (require('storage-available')('localStorage')) {
    // Yay!
}
else {
    // Awwww.....
}

2. Fall back to a shim

The easiest way to deal with the issue once we have detected the problem is to fall back to some other object that does not throw errors on every write.

memorystorage is a little library I wrote that follows the Web Storage API but just stores everything in memory. Because it uses the same API, you can use it as a drop-in replacement for localStorage and everything will function fine (though no data will survive page reload). It's Open Source so use as you please.

Background info

For more information on MemoryStorage and this issue in general, read my blog post on this topic: Introducing MemoryStorage .

I have set local storage key values through below logic using swift2.2

let jsStaring = "localStorage.setItem('Key', 'value')"
self.webView.stringByEvaluatingJavaScriptFromString(jsStaring)

Your first setItem example is correct. I don't believe that you can do the second option (localStorage["someKey"] = "someValue") though. Stick with the first one.

You mention hybrid - is it a PhoneGap or some other framework? Where in the app are you calling localStorage.setItem? If PhoneGap, be sure that everything has loaded via onDeviceReady first before trying to access localStorage:

<script type="text/javascript">
   // Wait for PhoneGap to load
   document.addEventListener("deviceready", onDeviceReady, false);

   // PhoneGap is ready
   function onDeviceReady() {
        window.localStorage.setItem("key", "value");
   }
</script>

Also, if the app freezes/stops working, in my experience it's because somewhere in the code you are accessing an object that is undefined. Perhaps try some debugging by checking if localStorage is undefined and logging it? Are you 100% sure that the "setItem" line is where it fails? Console.log is your friend, prove it! :)

if (localStorage === undefined) {
   console.log("oops, localStorage not initialized yet.");
}
else {
   window.localStorage.setItem("proDB", JSON.stringify(data));
   console.log("localStorage available.");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM