Apache Cordova
  1. Apache Cordova
  2. CB-1535

LocalStorage is not saved after first App launch on iOS 6

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.0
    • Fix Version/s: None
    • Component/s: iOS
    • Labels:
      None
    • Environment:

      iOS 6.0 - iOS Simulator
      iOS 6.0 - iPad 2

      Description

      1. Save a value in window.localStorage after a fresh install of the App in Simulator or iOS Device.
      2. Stop the App while running in Background.
      3. Restart the App and Restoring the value from window.localStorage is not possible (Error)
      4. Save a new value in window.localStorage
      5. Stop the App while running in Background.
      6. Restart the App and now you can restore the value (Everything runs fine from now on)

      To reproduce create a sample project with the "create" script.
      Put this Javascript into index.html or use the attached index.html.

      The Parameter BackupWebStorage is not changed.
      BackupWebStorage=YES

      <script type="text/javascript">
                  document.addEventListener("deviceready", onDeviceReadyToSave, false);
                  
                  function onDeviceReadyToSave() {
                      
                      var item = window.localStorage.getItem("key");
                      var message = "deviceready localStorage.getItem('key')="+item+" localStorage.length="+window.localStorage.length;
                      
                      console.log( message);
                      alert(message);
                      
                      if( item == null){
                          console.log("localStorage.getItem('key') is '"+item+"'");
                          item = "";
                      }
                      item = item + "value";
                      
                      window.localStorage.setItem("key", item);
                      console.log("calling localStorage.setItem('key', '"+item+"')");
                      
                      var value = window.localStorage.getItem("key");
                      console.log("verified localStorage.getItem('key')="+value);
                  }
              </script>
      
      
      1. index.html
        3 kB
        Christian Hemker

        Activity

        Hide
        Michal Mocny added a comment -

        ashok, seems unlikely that you are seeing the same issue as above. Please file a new bug with more description of your issue, or best yet, with a simple app that can reproduce the issue.

        (For the above issue, you should not need to add any code to CDVViewController, just make sure BackupWebStorage setting is set to "cloud" or "local")

        Show
        Michal Mocny added a comment - ashok, seems unlikely that you are seeing the same issue as above. Please file a new bug with more description of your issue, or best yet, with a simple app that can reproduce the issue. (For the above issue, you should not need to add any code to CDVViewController, just make sure BackupWebStorage setting is set to "cloud" or "local")
        Hide
        ashok mango added a comment -

        Hi..
        Im using coredova2.9 in ios
        i am getting the local storage issue with same as you discussed above..
        can you please explain where i need to put above code in CDVViewcontroller??
        and i am getting the issue as
        Failed to load webpage with error: The operation couldn’t be completed. (NSURLErrorDomain error -999.)

        Show
        ashok mango added a comment - Hi.. Im using coredova2.9 in ios i am getting the local storage issue with same as you discussed above.. can you please explain where i need to put above code in CDVViewcontroller?? and i am getting the issue as Failed to load webpage with error: The operation couldn’t be completed. (NSURLErrorDomain error -999.)
        Show
        Michal Mocny added a comment - https://issues.apache.org/jira/browse/CB-1558
        Hide
        Michal Mocny added a comment -

        Lee, thanks for mentioning, I'm filing a new issue for this.

        Show
        Michal Mocny added a comment - Lee, thanks for mentioning, I'm filing a new issue for this.
        Hide
        Lee Crossley added a comment -

        I have been testing the fix and found a problem. Here are the steps:

        1. A webdatabase is created by an App built with the iOS5 SDK and an earlier version of Cordova.

        2. The App is updated to use Cordova 2.1 (with the above fix) and built with the iOS6 SDK.

        3. Updating the app from 1 to 2 loses the webdatabase.

        I imagine this will be a common upgrade for most users.

        Show
        Lee Crossley added a comment - I have been testing the fix and found a problem. Here are the steps: 1. A webdatabase is created by an App built with the iOS5 SDK and an earlier version of Cordova. 2. The App is updated to use Cordova 2.1 (with the above fix) and built with the iOS6 SDK. 3. Updating the app from 1 to 2 loses the webdatabase. I imagine this will be a common upgrade for most users.
        Hide
        Michal Mocny added a comment -
        Show
        Michal Mocny added a comment - This should be fixed as of https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-ios.git;a=commit;h=1a6093513c51a817d1ef97ff87cb140519966e4d Please let me know if it is not.
        Hide
        Christian Hemker added a comment - - edited

        To get it working correct for iOS 6
        I moved also the call to restore from Backup Locations before instantiate UIWebView

        CDVViewController.m Line 201-205
            if (IsAtLeastiOSVersion(@"6.0")) {
                [CDVLocalStorage __restoreThenRemoveBackupLocations];
                [[NSUserDefaults standardUserDefaults] setBool:backupWebStorage forKey:@"WebKitStoreWebDataForBackup"];
            }
            // // Instantiate the WebView ///////////////
            [self createGapView];
        

        And changed the following if statement

        CDVViewController.m Line 232
            if (!IsAtLeastiOSVersion(@"6.0")) {
                if (backupWebStorage) {
                    [self.commandDelegate registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])];
                } else {
                    [CDVLocalStorage __restoreThenRemoveBackupLocations];
                }
            }
        
        Show
        Christian Hemker added a comment - - edited To get it working correct for iOS 6 I moved also the call to restore from Backup Locations before instantiate UIWebView CDVViewController.m Line 201-205 if (IsAtLeastiOSVersion(@ "6.0" )) { [CDVLocalStorage __restoreThenRemoveBackupLocations]; [[NSUserDefaults standardUserDefaults] setBool:backupWebStorage forKey:@ "WebKitStoreWebDataForBackup" ]; } // // Instantiate the WebView /////////////// [self createGapView]; And changed the following if statement CDVViewController.m Line 232 if (!IsAtLeastiOSVersion(@ "6.0" )) { if (backupWebStorage) { [self.commandDelegate registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])]; } else { [CDVLocalStorage __restoreThenRemoveBackupLocations]; } }
        Hide
        Michal Mocny added a comment -

        I'm working to get this landed, just working on verifying the solution now.

        Show
        Michal Mocny added a comment - I'm working to get this landed, just working on verifying the solution now.
        Hide
        Dewang Shah added a comment -

        I can also confirm that we were seeing the same issue with localStorage not being saved on first run. Christian's solution does fix the problem.

        Thanks Christian.

        Show
        Dewang Shah added a comment - I can also confirm that we were seeing the same issue with localStorage not being saved on first run. Christian's solution does fix the problem. Thanks Christian.
        Hide
        Ben BIrch added a comment -

        We noticed several regressions between iOS5 and iOS6 with localStorage integrity. Can confirm that the fix above works.

        Show
        Ben BIrch added a comment - We noticed several regressions between iOS5 and iOS6 with localStorage integrity. Can confirm that the fix above works.
        Hide
        Christian Hemker added a comment -

        The problem is the UIWebView is created earlier than the new Key WebKitStoreWebDataForBackup is set with NSUserDefault.
        If I set the Key WebKitStoreWebDataForBackup before the UIWebView is created everything seems to run correct.
        With this change the localStorage is saved during restart of the app.

        CDVViewController.m Line 204
        if (IsAtLeastiOSVersion(@"6.0")) {
                [[NSUserDefaults standardUserDefaults] setBool:backupWebStorage forKey:@"WebKitStoreWebDataForBackup"];
        }
        //// Instantiate the WebView ///////////////
        [self createGapView];
        
        Show
        Christian Hemker added a comment - The problem is the UIWebView is created earlier than the new Key WebKitStoreWebDataForBackup is set with NSUserDefault. If I set the Key WebKitStoreWebDataForBackup before the UIWebView is created everything seems to run correct. With this change the localStorage is saved during restart of the app. CDVViewController.m Line 204 if (IsAtLeastiOSVersion(@ "6.0" )) { [[NSUserDefaults standardUserDefaults] setBool:backupWebStorage forKey:@ "WebKitStoreWebDataForBackup" ]; } //// Instantiate the WebView /////////////// [self createGapView];
        Hide
        Christian Kuetbach added a comment -

        I think I have an idea, why this happens:

        The first time, the app loads the localStorage is not persistent. The flag will be set by cordova. The localStorage is loaded from the cache folder. Everything will be stored in the files located in that folder.

        From the second time forward the localStorage is loaded from another (persitent) folder. All changes are stored there.

        Show
        Christian Kuetbach added a comment - I think I have an idea, why this happens: The first time, the app loads the localStorage is not persistent. The flag will be set by cordova. The localStorage is loaded from the cache folder. Everything will be stored in the files located in that folder. From the second time forward the localStorage is loaded from another (persitent) folder. All changes are stored there.
        Hide
        Christian Hemker added a comment -

        index.html to reproduce in sample project.

        Show
        Christian Hemker added a comment - index.html to reproduce in sample project.

          People

          • Assignee:
            Michal Mocny
            Reporter:
            Christian Hemker
          • Votes:
            2 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development