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.
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