Ответ 1
Столкнувшись с той же проблемой, я никогда не находил никакого решения, кроме как добавить WKWebView в иерархию представления и переместить его за экран с помощью AutoLayout. К счастью, этот обходной путь работает надежно.
Я хочу переключиться на WKWebView
с UIWebView
. В моем коде экземпляр веб-представления создается вне экрана (без привязки к иерархии представления), и URL-адрес загружается. Когда загрузка будет завершена, веб-представление будет представлено пользователю в отдельном UIWindow (например, в промежуточной рекламе). Все отлично работает с UIWebView
; но после переключения на WKWebView
angular код javascript ведет себя неожиданным образом.
Проведя некоторые исследования, я выяснил, что таймеры javascript (и загрузчики HTTP) приостанавливаются, когда экземпляр WKWebView
не присоединен к иерархии представления: если вы запускаете таймер в javascript, который работает в отдельном WKWebView
- он не будет запущен, пока не будет прикреплено веб-представление.
Кто-нибудь может предложить возможный обходной путь (помимо присоединения скрытого веб-вида к ключевому окну и затем перемещения его в другое окно)?
Я создал образец проекта, чтобы продемонстрировать проблему (или, более вероятно, функцию WebKit)
https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip
Тестовое приложение загружает веб-страницу с JavaScript, который планирует таймер и загружает HTTP-запрос. Вы можете использовать переключатели, чтобы показать/скрыть веб-представление (задает свойство 'hidden') и прикрепить/отсоединить его от иерархии представления.
Если веб-вид прикреплен (скрыт или видим), и вы нажали Load
, JavaScript прекрасно работает: вы можете увидеть диалоговое окно с предупреждением success
или failure
. Если он отключен - таймер сработает только тогда, когда он подключен к иерархии представлений (переключите "Detached" в "on", нажмите "Load", подождите пару секунд и снова переключитесь в "off"). Вы также можете проверить console.log
в Safari Web Inspector.
Вот источник тестовой веб-страницы:
<!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>
И 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;
};
}]);
Столкнувшись с той же проблемой, я никогда не находил никакого решения, кроме как добавить WKWebView в иерархию представления и переместить его за экран с помощью AutoLayout. К счастью, этот обходной путь работает надежно.