Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix window.location issue in iOS9 UIWebview

Since iOS9 release, my web app does not work anymore. The application uses a url hash based navigation and route changes trigger in a unpredictable way since iOS9.

I made a lot of researches and find the issue in the managing of window.location in IOS9 UIWebview.

Related to this post, the angular community seems to have fixed the issue with a released patch for angular.js.

https://gist.github.com/IgorMinar/863acd413e3925bf282c

The issue has been identified as : The iOS9 UIWebview doesn't update the href synchronously while using window.location

I looked through their corrections for in IOS9 but I don't find a way to reproduce their correction to make it works with any (non angular) webapp.

https://github.com/angular/angular.js/commit/8d39bd8abf423517b5bff70137c2a29e32bff76d#otherHash https://github.com//petebacondarwin/angular.js/commit/47f16f35c213dbb165567102231ac1496246c456 https://github.com//angular/angular.js/blob/master/src/ng/browser.js

Does someone found or is working on a solution to make the angular solution work in any (non angular) web app?

Update:

This is the kind of link I'm calling

domain/player/index.html

then

domain/player/index.html#/online/presentation/ru1XA0nkvgHm/slide/0

with

[self.view stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"window.location.href = '#/offline/presentation/%@/slide/%ld?isNativeApp=1%@%@'",moduleId,(long)slideNumber,infoIcons,testingMode]]);

I made tests and found something strange.

If I make a double call with the last command, the second time, the hashchange event triggers.

I don't want to have to resubmit the app to the app store, I want to modify my html (that can be fetched from the server) to detect the hash change and make the app work.

like image 668
user1751482 Avatar asked Jan 08 '23 12:01

user1751482


2 Answers

The problem is that this particular browser does not update the value for window.location.href until the next run of the JavaScript event loop. This means that if you write to that value then immediately read it back you get a different value:

console.log(window.location.href)   // -> http://my.domain.com/path/to/page
window.location.href = 'http://my.domain.com/path/to/other/page';
console.log(window.location.href)   // -> http://my.domain.com/path/to/page

// next tick of the event loop

console.log(window.location.href)   // -> http://my.domain.com/path/to/other/page

Notice that the second console.log returns the old value, not the new value. After the current event loop completes, the value is updated, as can be seen in the third console.log.

The fix that we have come up with, is to cache the value that we wrote, if the browser is not updating synchronously, and then to use that value from then on, instead of the value returned from window.location.href, until there is a hashchange event, which tells us that the browser has finally sorted itself out.

Here is a link to the commit in AngularJS where this is fixed: https://github.com/angular/angular.js/commit/8d39bd8abf423517b5bff70137c2a29e32bff76d

like image 112
Pete BD Avatar answered Jan 28 '23 14:01

Pete BD


window.setTimeout(function(){
      //the second time you update your url.
      updateUrl();
},0);

The bug is because of in IOS 9 ,the location.href/location.hash would not change immediately when you change that like this: location.href = http://yoururl.com , it will be changed in the next Event Loop. Adding window.settimeout will force the code to be execute in the next Event Loop.

like image 42
Rongrong Luo Avatar answered Jan 28 '23 13:01

Rongrong Luo