7

In my application I am using window.history.back to navigate back to previous View

Declaration of back button

 <div class="back_icon"  id="verification_back_icon"><a href="#" data-rel="back"  data-transition="slidedown"><img src="images/back_btn.png" width="23"/></a></div>

Button action:

$( "#verification_back_icon" ).on( "click", function ( e ) {
    if ( checkDirtyVacation() ) {
        e.preventDefault();
        if ( backbtnAlt == false ) {
            backbtnAlt = true;
            confirm( "All data will be lost. Do you want to continue?",
                function ( r ) {
                    if ( r ) {
                        //onBackKeyDown();
                        clearVacationvalues();
                        window.history.back();//this is not working in iOS 9
                    } else {

                    }
                    backbtnAlt = false;
                } );
        }
    }
    else {
        e.preventDefault();
        if ( $( ".vaction_location" ).hasClass( "chkSelect" ) ) {
            $( ".vaction_location" ).removeClass( "chkSelect" );
            $( ".vaction_location" ).addClass( "chkUnSelect" );
        }


        window.history.back();
    }
} );

This worked perfectly till iOS 8.4. In iOS 9 this navigation is not working.

I am using Apache Cordova native platform version 3.8.0 .

If anyone facing the similar problem please suggest me. I have tried with history.back doesn't work on iOS using Cordova, but no luck

Thank you.

Rajib Chy
  • 800
  • 10
  • 22
soumya
  • 3,801
  • 9
  • 35
  • 69
  • If your "previous view" uses hashes, then your problem is probably due to the fact that setting of `window.location.hash` is asynchronous is iOS 9 UIWebView - [see here](https://openradar.appspot.com/22186109). Hard to know without more details of what framework(s) you are using... – DaveAlden Sep 24 '15 at 18:53
  • @DaveAlden ..thank you for response..Please see my updated question – soumya Sep 25 '15 at 05:27
  • From your html snippet, it looks you may be using jQuery mobile? If so, what version? If not, give example of how you navigate between views – DaveAlden Sep 25 '15 at 05:37
  • Yes I am using Jquery mobile version: jQuery Mobile 1.4.5 @daveAlden – soumya Sep 25 '15 at 06:01

6 Answers6

7

The problem is that setting of window.location.hash is asynchronous in the iOS 9.0 UIWebview (used by Cordova/Phonegap) - see this bug report for details.

This causes issues when using jQuery Mobile which by default uses window.location.hash to navigate between "pages". It also causes issues with popups/dialogs/select menus which use this mechanism.

You can fix this by preventing jQuery Mobile from automatically listening/using location.hash:

$(document).on("deviceready", function(){
    $.mobile.hashListeningEnabled = false;
});

However, I found this had side effects on Android such as causing the hardware back button not to work, so I targeted it specifically at iOS 9 using cordova-plugin-device:

$(document).on("deviceready", function(){
    if(device.platform === "iOS" && parseInt(device.version) === 9){
        $.mobile.hashListeningEnabled = false;
    }
});

Note that I'm using navigator.app.backHistory() not window.history.back() in conjunction with hashListeningEnabled = false - this may make a difference.

Alternatively you can use this plugin to use the new WKWebView on iOS 8 and 9. WKWebView is used by Safari on iOS 8+, hence JQM sites viewed in the browser on iOS 9 don't encounter these issues. cordova-ios 3 still uses UIWebView due to a bug in WKWebView in iOS 8, but the upcoming cordova-ios 4 will support a WKWebView core plugin for iOS 9+. Note that there are additional considerations when using WKWebView with Cordova/Phonegap apps due to its stricter security, such as requiring CORS headers on XHR responses.

DaveAlden
  • 30,083
  • 11
  • 93
  • 155
  • after using $.mobile.hashListeningEnabled = false; in ondeviceReady method, the navigation click is not working. Earlier it popped back to loading page irrespective of forward navigation clicks count. – soumya Sep 25 '15 at 08:41
  • If that doesn't work, WKWebView may be a better option – DaveAlden Sep 25 '15 at 08:52
  • Should I replace UIWebView with WKWebView in interface builder?I will try this once.. – soumya Sep 25 '15 at 09:03
  • Don't know how your are building it (locally or cloud service), but yes try and see if WKWebView resolves the issues. If you go with WKWebView though be sure to do a good regression test as it may cause other issues. – DaveAlden Sep 25 '15 at 09:23
  • Do you know how to use WKWebView instead of UIWebview in mainViewController (here I am have it as - (void)webViewDidFinishLoad:(UIWebView*)theWebView ) – soumya Sep 25 '15 at 10:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/90597/discussion-between-sujania-and-davealden). – soumya Sep 25 '15 at 10:17
4

I think it is the A tag's default action causes the bug. So I just prevent the default action by adding return false at end of the click handler function

And it works.

  • html

<a id="back-btn">back</a>

  • javascript

    $('#back-btn').on('click', function(e) {
           window.history.go(-1);
           return false;
        })
    
dannyliu
  • 131
  • 5
2

SOLUTION:

This line resolved my issue :

 history.go(0); 

I have replaced window.history.back() with history.go(0);

Now it is working fine for me in iOS 9

In index.html

   <script type="text/javascript">$.mobile.hashListeningEnabled = false;</script>

Add this in onDeviceReady function:

function onDeviceReady() {
    if ( device.platform === "iOS" && parseInt( device.version ) === 9 ) {
        $.mobile.hashListeningEnabled = false;
    }

    if ( !( $.mobile.hashListeningEnabled &&
        $.mobile.path.isHashValid( location.hash ) &&
        ( $( hashPage ).is( ":jqmData(role='page')" ) ||
            $.mobile.path.isPath( hash ) ||
            hash === $.mobile.dialogHashKey ) ) ) {

        // make sure to set initial popstate state if it exists
        // so that navigation back to the initial page works properly
        if ( $.event.special.navigate.isPushStateEnabled() ) {
            $.mobile.navigate.navigator.squash( path.parseLocation().href );
        }

        $.mobile.changePage( $.mobile.firstPage, {
            transition: "none",
            reverse: true,
            changeHash: false,
            fromHashChange: true
        } );
    } else {
        // trigger hashchange or navigate to squash and record the correct
        // history entry for an initial hash path
        if ( !$.event.special.navigate.isPushStateEnabled() ) {
            $window.trigger( "hashchange", [true] );
        } else {
            // TODO figure out how to simplify this interaction with the initial history entry
            // at the bottom js/navigate/navigate.js
            $.mobile.navigate.history.stack = [];
            $.mobile.navigate( $.mobile.path.isPath( location.hash ) ? location.hash : location.href );
        }
    }
}

Validation for device OS version (as history.go(0) is working only with iOS 9) Prior to iOS 9 version window.history.back() working perfectly

And now Add this piece of code in place of window.history.back()

if ( device.platform === "iOS" && parseInt( device.version ) === 9 ) {
    console.log( "version" + device.version );
    console.log( "iOS 9" );
    history.go( 0 );
    //write your code here                 
}
else {
    window.history.back();
}

To fix this Message "Failed to load webpage with error: CDVWebViewDelegate: Navigation started when state=1" in console add below code in CDVWebViewDelegate.m

In - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType

Method Comment this piece of code shown below:

/*if ([_delegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) {
    NSDictionary* errorDictionary = @{NSLocalizedDescriptionKey : description};
    NSError* error = [[NSError alloc] initWithDomain:@"CDVWebViewDelegate" code:1 userInfo:errorDictionary];
    [_delegate webView:webView didFailLoadWithError:error];
}*/
Rajib Chy
  • 800
  • 10
  • 22
soumya
  • 3,801
  • 9
  • 35
  • 69
  • Navigation is working fine , where as I am getting this line in Console: CDVWebViewDelegate: Navigation started when state=1 Failed to load webpage with error: CDVWebViewDelegate: Navigation started when state=1 – soumya Sep 28 '15 at 12:49
  • Does any one know whether this behaviour is a minor or major issue? – soumya Sep 28 '15 at 12:50
2

Disabling push state worked for me:

$.mobile.pushStateEnabled = false;

Ian Drake
  • 121
  • 1
  • 3
  • @lan Drake this is really working great unlike my solution .This is not giving any "navigation started when state =1 " issue..Thank you for the solution. – soumya Oct 13 '15 at 05:55
  • after disabling pushState by above way, could I use "navigator.app.backHistory()" for back ? – Nimesh khatri Oct 13 '17 at 10:19
1

@Sujania,

According to the phonegap team, iOS9 is not officially support. This issue may be yet another bug in iOS9. You may have to wait for a fix.

PhoneGap Build iOS 9 Support Status
http://community.phonegap.com/nitobi/topics/phonegap-build-ios-9-support-status

Top line: iOS 9 is not officially supported until Cordova-iOS 4.0.0, which the Cordova team is hard at work on. However some issues can be solved with some simple configuration changes.

At this point in time, 4 bugs are reported to the Cordova Bug repository. Your issue does not appear in the respository - as of this date.

https://issues.apache.org/jira/browse/CB-9684?jql=text%20~%20%22iOS9%22

  • Regardless, of what you are using, as the forum post states *iOS 9 is not officially supported until Cordova-iOS 4.0.0*. This means, create a work around, or wait until it is officially supported. **OR** file a bug report with cordova. **OR** wait until someone else creates a work around. For my part, I do not work on leading edge, so I am the wrong person to follow up with. --Best of Luck. –  Sep 25 '15 at 05:36
0

Try this

if(r){
         try{
          var nav = window.navigator;
          if( this.phonegapNavigationEnabled && nav && nav.app && nav.app.backHistory )
          {
            nav.app.backHistory();
          }
          else 
          {
            window.history.back();
          }
        }
        catch(e)
        {
         alert(e);
        }
      }
Sunil
  • 919
  • 15
  • 25
  • thank you for your response..But still the same issue ..My view does not pops back correctly – soumya Sep 24 '15 at 12:42