I want to switch to WKWebView
from UIWebView
. In my code, the web view instance is created offscreen (without attaching to the view hierarchy) and URL is loaded. When loading is done, the web view is presented to the user in a separate UIWindow (like an interstitial ad). Everything works fine with UIWebView
; but after switching to WKWebView
, the angular javascript code behaves in an unexpected way.
After doing some research, I've figured out that javascript timers (and HTTP loaders) are suspended when the WKWebView
instance is not attached to the view hierarchy: if you start a timer in javascript which runs in detached WKWebView
- it won't be fired until the web view is attached.
Can anyone suggest a possible workaround (besides attaching a hidden web view to the key window and then moving it to another window)?
I've created a sample project to demonstrate the issue (or, more likely, a WebKit feature)
https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip
The test application loads a web page with javascript which schedules a timer and loads HTTP request. You can use switches to show/hide web view (sets 'hidden' property) and attach/detach it from the view hierarchy.
If the web view is attached (hidden or visible) and you hit Load
, the javascript works fine: you can see success
or failure
alert dialog. If it's detached - the timer will only fire when it's attached to the view hierarchy (switch "Detached" to "on", hit "Load", wait a couple of seconds and switch back to "off"). You can also check console.log
from Safari Web Inspector.
Here's the test web page source:
<!doctype html>
<html ng-app="project">
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="project.js"></script>
</head>
<body>
<div id="simple" ng-controller="MyController" data-ng-init="callNotify(message);">
</div>
</body>
</html>
And the javascript:
angular.
module('project', []).
controller('MyController', ['$scope','notify', function ($scope, notify) {
$scope.callNotify = function(msg) {
notify(msg);
};
}]).
factory('notify', ['$window', '$http', '$q', '$timeout', function(win, $http, $q, $timeout) {
return function(msg) {
deferred = $q.defer();
$timeout(function() {
$http.get('http://jsonplaceholder.typicode.com/posts').
success(function(data, status, headers, config) {
alert("success");
console.log("success")
}).
error(function(data, status, headers, config) {
alert("error");
console.log("error")
});
});
return deferred.promise;
};
}]);
See Question&Answers more detail:
os