Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
/**
* ================== angular-ios9-uiwebview.patch.js v1.1.1 ==================
*
* This patch works around iOS9 UIWebView regression that causes infinite digest
* errors in Angular.
*
* The patch can be applied to Angular 1.2.0 – 1.4.5. Newer versions of Angular
* have the workaround baked in.
*
* To apply this patch load/bundle this file with your application and add a
* dependency on the "ngIOS9UIWebViewPatch" module to your main app module.
*
* For example:
*
* ```
* angular.module('myApp', ['ngRoute'])`
* ```
*
* becomes
*
* ```
* angular.module('myApp', ['ngRoute', 'ngIOS9UIWebViewPatch'])
* ```
*
*
* More info:
* - https://openradar.appspot.com/22186109
* - https://github.com/angular/angular.js/issues/12241
* - https://github.com/driftyco/ionic/issues/4082
*
*
* @license AngularJS
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
angular.module('ngIOS9UIWebViewPatch', ['ng']).config(['$provide', function($provide) {
'use strict';
$provide.decorator('$browser', ['$delegate', '$window', function($delegate, $window) {
if (isIOS9UIWebView($window.navigator.userAgent)) {
return applyIOS9Shim($delegate);
}
return $delegate;
function isIOS9UIWebView(userAgent) {
return /(iPhone|iPad|iPod).* OS 9_\d/.test(userAgent) && !/Version\/9\./.test(userAgent);
}
function applyIOS9Shim(browser) {
var pendingLocationUrl = null;
var originalUrlFn= browser.url;
browser.url = function() {
if (arguments.length) {
pendingLocationUrl = arguments[0];
return originalUrlFn.apply(browser, arguments);
}
return pendingLocationUrl || originalUrlFn.apply(browser, arguments);
};
window.addEventListener('popstate', clearPendingLocationUrl, false);
window.addEventListener('hashchange', clearPendingLocationUrl, false);
function clearPendingLocationUrl() {
pendingLocationUrl = null;
}
return browser;
}
}]);
}]);
Owner

IgorMinar commented Sep 11, 2015

I've updated the gist to v1.0.3 which should do better job of useragent sniffing and support iPad Air. Thanks @JeremyPlease for bug reports

Owner

IgorMinar commented Sep 11, 2015

v1.1.0 should resolve all of the "flicker" issues seen in apps that use ui-router.

Fantastic - works well for me...

tenfef commented Sep 14, 2015

Thanks for the patch. Can you please update the comments from:
dependency on the "ngIOS9Patch" module to your main app module. to
dependency on the "ngIOS9UIWebViewPatch" module to your main app module.

Delagen commented Sep 14, 2015

Please add array notation to config call

.config(["$provide", function($provide) {

Well, as far as I understand this code, everything after line 44 (return $delegate;) is dead code, since it never gets executed (except the function definitions). Am I right? If yes, why?

deebloo commented Sep 14, 2015

@tobiasmuecksch Those are function declaration which are hoisted to the top when the code runs. Therefore they can be placed anywhere the author decides makes them most readable.

pille72 commented Sep 14, 2015

@deebloo does this have any advantages or is this just a different way to write js code?

After install the patch I get this error in xcode for all phones. iPads are OK

import <UIKit/UIKit.h>

int main(int argc, char* argv[])
{
@autoreleasepool {
int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
return retVal;
}

With error: Thread 1:signal SIGABRT on int retVal......

deebloo commented Sep 14, 2015

@pille72 To me it can make your code more readable. The code reads from top down so people see how things are done and then they can go find the implementation details if they need to. For example if you are reading through some code and you see isIOS9UIWebView(), you can assume it will tell you whether or not you are in an IOS9 webview, maybe you don't care how it does it, you just need to know that it does it and you can then go investigate as your need.

tl;dr show anyone reading the code the most important / relevant information first.

col commented Sep 16, 2015

Maybe consider adding "use strict"; at the top of the file. The patch already adheres to strict mode and this will not have any adverse effects for people running on ECMAScript earlier than version 5.

col commented Sep 16, 2015

I'm getting a some issues when using minification. Please update the script to support minification.

Example:

angular.module('ngIOS9UIWebViewPatch', ['ng']).config(['$provide', function($provide) {
  ...
}]);

marrs commented Sep 17, 2015

Just came here to say the same thing. Spent the afternoon working this out :)

Owner

IgorMinar commented Sep 18, 2015

v1.1.1 is out, I fixed the minification issue as well as the incorrect module name in the comment.

vasam commented Sep 18, 2015

where this patch file should be placed? under /angular/ ?

Thanks.

dmastag commented Sep 18, 2015

@vasam you can place it anywhere you like since you will include it in your index.html with the path to it

WTH man. Is apple becoming Microsoft? Feel like I am developing for Internet Exploder again.

hammady commented Sep 19, 2015

For those who couldn't get this patch to the rescue, make sure you don't have href="#" on your elements that trigger the $location change.

F1LT3R commented Sep 20, 2015

Having trouble getting this patch to work here:

Uncaught Error: [$injector:modulerr] Failed to instantiate module ModuleName due to: Error: [$injector:modulerr] Failed to instantiate module ngIOS9UIWebViewPatch due to: Error: [ng:areq] Argument 'fn' is not a function, got string

screen shot 2015-09-20 at 11 22 14 am

Hi, the patch fixed the issue with my pages, however has now caused errors with two icon buttons on my app landing page which trigger intro tutorials if the first time entering that section of the app. On clicking the icon it just flickers and stays on the menu. Commenting out the tabClick() and replacing with the original URL allows me to enter the next screen (disabling the tutorials) - but would ideally like to have them remain in the app.

homeIcons : [

            {
                title : 'Contacts',
                //state : 'app.upload-device',
                iconOn : 'ion-plus',
                iconOff : 'ion-plus',
                tabClick: 'contactTabClick()'
                //url : '#/app/emergency-profiles'
            },

            {
                title : 'My Trips',
                //state : 'app.upload-camera',
                iconOn : 'ion-ios-people',
                iconOff : 'ion-ios-people',
                tabClick: 'myTourTabClick()'
                //url : '#/app/my-tours'
            },
            {
                title : 'Travel Tools',
                state : 'app.upload-camera',
                iconOn : 'ion-ios-location',
                iconOff : 'ion-ios-location',
                url : '#/app/travel-tools'
            },
        ],

Works really for me, thank you :)

rmjoia commented Sep 22, 2015

Guys! Thanks a lot, I was having some issues here, and end up finding this code! I'm integrating an angular.js spa on a webview using appcelerator titanium alloy, this patch did the trick.

what about adding a bower.json file:

{
  "main": [
    "angular-ios9-uiwebview.patch.js"
  ],
  "name": "angular-ios9-uiwebview.patch",
  "version": "1.1.1"
}

so it is easy to add this patch to a project within the bower.json of the project:

"angular-ios9-uiwebview-patch": "https://gist.github.com/<revision>.git",

Thanks a lot for the patch... I was going around and around until I found this :o)

@IgorMinar it seems you have identified and corrected the issue in angular.
It would be useful if you could give us a fix that correct the iOS9 'window.location' issue on any web applications

It works like a charm! Thank you!

ciriac commented Sep 22, 2015

Can confirm that this works. Thanks!

do you know if its ok to have something like:

<a href ng-click="doStuffThenChangeLocation()">hello</a>

where $scope.doStuffThenChangeLocation is a function that does stuff before changing $location

Definitely fixed my issues with Ionic tabs in iOS 9.1 beta! Thanks!

Works for me. Thanks!

I applied the patch and it worked except I came across another issue.
When a user logout from home screen I open login screen. But while the transition is happening Home screen is appearing for a moment behind login page. It is not consistent and happens sometimes. This happens only in iOS 9.
I use
$ionicHistory.nextViewoptions({
disableBack:true,
historyroot:true
});
$state.go('login');
To go to login page

issue

Any one came across such an issue?
Please help.

bentaly commented Sep 23, 2015

THANKYOU!

Been looking for hours for a fix πŸ‘

Maybe someone can help me with this ? getting error: uknown provider ngIOS9UIWebViewPatch

Amazing! Thank you so much for this fix.

Awesome, thanks for the fix.
Angular 1.4.6 doesn't fix this issue completely.

Same for me,

Newer versions of Angular have the workaround baked in.

seems not entirely true for Angular 1.4.6

It worked for a circumstance I was experiencing with my angular only app. Thank you!

Worked for me too.. Many thanks ! πŸ‘

EeKay commented Sep 28, 2015

It scares the digest warnings away like little kids on a graveyard.. sweet :)

Works great! @IgorMinar, I appreciate it.

if anyone us jshint or jscs here is a gist with https://gist.github.com/DrMabuse23/307d1f81727c0327fff0

vqoph commented Sep 29, 2015

Worked for me too

@pellekrogholt and others: I've gone ahead and put this solution up on bower and NPM. Repo is available at https://github.com/azaslavsky/angular-ios9-uiwebview-patch

Bower:

bower install angular-ios9-uiwebview-patch

NPM:

npm install angular-ios9-uiwebview-patch

Using this fix solved my issue with getting the errors. However, now when I use $state.go('urldestination') it takes me to the destination the first time. However, when I use it again... It takes me back to the $urlStateProvider.otherwise('destination');
Any ideas on why this is happening?

sangwonl commented Oct 4, 2015

It works for me perfectly! Super thanks!!

It worked pretty well. Hope Apple fix the issue on their side as well.

This is not working for me on Angular 1.4.7 which should have fixed this issue.

samrose3 commented Oct 4, 2015

Thank you!! I was going in circles trying to figure out why this was happening! Patch worked like a charm!

Thanks it works perfectly!!!

Worked for me as well....Thanx dev

denstepa commented Oct 5, 2015

big thanks for this fix!

iad42 commented Oct 5, 2015

thanks! this helped me a lot

I'm running 1.4.3 and for some reason, this fix doesn't work for me: http://puu.sh/kAkGS/ba5f24ef18.png

Worked for me! My tabs were flickering terribly - now they are perfect. Thank you!

Having the same issues as zwallacedev:

When I use $state.go('urldestination') it takes me to the destination the first time. However, when I use it again... It takes me back to the $urlStateProvider.otherwise('destination');

Anybody else had this when the patch is applied?

Thanks

Yes I still have the issue post patch but it's intermittent. Almost like after a while it goes away and stays away. Prior to patching it was easy to reproduce.

Oh and it might be worth debugging the code that detects ios9 to make sure it's returning true during execution.

function isIOS9UIWebView(userAgent) {
      return /(iPhone|iPad|iPod).* OS 9_\d/.test(userAgent) && !/Version\/9\./.test(userAgent);
    }

Thanks allot...I was worried as clients reported issues faced in IOS 9...applied you patch and it worked!!

idir commented Oct 12, 2015

Thank you ^^

Our app is stable with your patch. We're still testing, but so far the tab bouncing problem seems gone. Thank you!

HarunOr commented Oct 14, 2015

Works like a charm !

Thanks a lot!

Question,

since making the update and including the patch everything works well. However, window.histroy.back() no longer works.

Is there an alternative way to implement back funcionality?

Thanks

Hey Igor, Thanks a lot for this patch! works perfectly πŸ‘

I just wanted to know about the licensing aspects of using this patch. Our application is in production and currently used Angular 1.3.16 and upgrade to 1.4.6 is not yet planned. So does the patch have any licensing restrictions in terms of using it in production?

Regards,
Vinod

strille commented Oct 15, 2015

Looks great... I have one concern though:

It seems this patch doesn't check which version of Angular you're running and then only decorates $browser for the versions where it's needed? I'm slightly worried that if we apply this patch and then upgrade to an Angular version with this fixed baked in, and forget to remove the patch, we could run into subtle problems...

This issue was driving me nuts. Thank you so much for this patch!

Great!!!! Thank you very much!!

Thanks for the patch! Works great!

sprsoft commented Oct 16, 2015

You saved my day! This issue was annoying me! Thank you so much for this path!

Works great, thanks!

Wow it works great! Thank you ^^

I've noticed that the ngAnimate transitions aren't working in ios9's web view when this is used in a cordova app, they do work in Safari in ios9 however.

mudbath commented Oct 22, 2015

Thanks for this!

This saved my life, thanks!

truth86 commented Oct 23, 2015

Perfect works. I think that ionic team have to consider of your code in their framework.
Thanks again... πŸ‘ πŸ‘ πŸ‘

jackrr commented Oct 23, 2015

This is great, thank you!

Dude this works great! Thanks :) iOS 9.1, Angular 1.4.3

polunzh commented Oct 26, 2015

Nice!

Yep works great!!

Hello guys, I'm working on a ionic/angular app, and I used this patch to fix the ios 9 things, but it's not working for me.
It's the 2nd project I used it, it works well on the 1 project, iOS 9.0.2 angular 1.4.7
but it's not working with my 1st project iOS 9.0.2 which was angular 1.4.3 but I update it to angular 1.4.7

Do I have to update to iOS 9.1 to fix this bug ?
thanks

EDIT : I update my iphone to iOS 9.1 and still not working, I have no idea what to do :(

fvaletk commented Oct 27, 2015

Works perfectly, Thanks!

@Spymannn did it work once you upgraded to 1.4.7?

Hi. Using the patch above, we haven't had luck fixing Tab jumping as explained here: driftyco/ionic#4563

@ewhitmore no, unfortunately, this is really weird because I tried it in another project and it works perfectly
I thought that it was fix in angular 1.4.7 but apparently not

Thanks

I am working on project for mobile website. I have used Ionic Framework. I am having issue in navigating to next state on safari browser on iOS 9. It is giving Dom 12 exception setRequestHeaderError
I have used above patch as well but still getting error.

-----------------------------Update-----------------------------------------------------------------------
Patch was not working for me. I have used below code and it worked:
add below code in your module

.factory('httpInjector', function () {
        var httpInjector= {
            request: function (config) {

                if(config.headers.Authorization.toLowerCase().trim() == 'basic')
                {
                    if(config.headers.Authorization)
                    {
                        delete config.headers.Authorization;
                    }
                }
                config.headers["Access-Control-Allow-Origin", "*"];
//                config.headers["Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"];
//                config.headers["Access-Control-Allow-Methods", "GET, PUT, POST"];

                return config;
            }
        };
        return httpInjector;
    }).config(['$httpProvider', function ($httpProvider) {
        $httpProvider.interceptors.push('httpInjector');
}]);

It saves my life. Thanks

Fixed the glitches on ios. Thanks a lot ! πŸ‘

kapil019 commented Nov 4, 2015

@IgorMinar All transition issue are resolved except. One black background is showing behind page transition.
Please suggest any option to resolve black background issue.

You Sir, are a lifesaver - thank you!

It works for me perfectly! Many thanks!!

sdidyk commented Nov 5, 2015

thx, bro

@IgorMinar, Thanks a lot brother.

thanks a lot.

Thanks man.

@pcrombach did you solve the problem? I have exactly the same problem!!

tekolie commented Nov 10, 2015

Thanks a lot!

lvbeck commented Nov 11, 2015

thanks

@kapil019 Ionic tip: to prevent flashes of a black background, make sure you set ion-nav-view's background-color to transparent.

https://github.com/Telerik-Verified-Plugins/WKWebView

ddbaron commented Nov 14, 2015

Bug fixed in Ionic v1.1.1 -> you don't need this patch any more as it is addressed in ios9 location patch ionic-team/ionic@e5b85df

swren commented Nov 17, 2015

Thank you!! this fixed the issue for my App immediately.

I was getting multiple "[$rootScope:infdig] 10 $digest() iterations reached" errors

Cheers

asemoon commented Nov 17, 2015

@ddbaron I am running latest version of ionic , however, I am getting "10 $digest() iterations reached" message upon using $state.go. It only happens when I run the app on the device and it seems to be ok when using ionic serve.

I'm having a weird issue on iOS whereby i have a form the ppl hv to input their phone numbers nd it saves and displays the number in another page.

I save first number 0123456789 it saves and displays correctly but when i save another number, it attaches the previous number to the new number although in my db it doesn't save both as one number. but somehow this number is cached on my view page nd shows. everything other field shows correctly but only the number field.

Happens only on iOS not on Android

This patch works fine for AngularJS v1.3.13 as well. Thanks to the Author!

Thank you!!!!

renanss commented Dec 4, 2015

Some heroes doesn't need a cape. They are coder heroes.
You saved our day, thank you so much!

kettula commented Dec 9, 2015

Beautiful. Thank you!

edsykes commented Dec 15, 2015

updating to the latest version of ionic ( 1.1.1 ) also fixes the issue that this patch addresses

thanks a lot ... its works for me..

WOrks perfect. thanks πŸ‘

Did anyone tried this patch with Cordova-ios 4.0.1? On Cordova-ios 3.9.2, this patch works perfectly but if I update to 4.0.1, I still run into an infinite loop when Angular starts. Using ionic 1.1.1 or 1.2.1 does not make any difference. Thanks

Snaddu commented Jan 7, 2016

@hammady. Thank you for reminding about this. Solved my case!

Do we need to apply this change if we use ionic 1.2.0?

@mathieugerard same here...

@dorshay6, @edmondchui: It's already included in 1.2.0.

@IgorMinar: Iam using ionic framework, I found the problem with css "overflow" attribute (using bootstrap class "table-responsive"), at android it's working fine, but at ios9 can't scroll horizontal.

jpike88 commented Mar 25, 2016

Does this patch apply to WKWebView?

Does any one have a clue if similar patch is needed for ios 10?

@mihneasim: I found the same issue in ionic app when using com.passslot.cordova.plugin.passbook when testing on ios 10. After invoking the pass screen and clicking on add, navigating away from the app screen that caused the invoke was causing 10 $digest() iterations reached. For now, I have locally added the ios 10 check to the patch for my project and things are working fine.

vahidvdn commented Nov 2, 2016

This didn't solve my problem. My app works fine in android and ios10, but doesn't work nice in some cases in ios9.

Helo I did one hybrid app that was properly working in android, but in iOS its working but getting problem at booking time slots are not working any ideas. here is my screenshot.
screen shot 2017-02-06 at 5 43 09 pm
Thanks in advance.

tuanbs commented Mar 17, 2017

I used this patch but still have this issue with Ionic 1.3.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment