Pregunta Ejecución WKWebKit javascript cuando no está conectado a una jerarquía de vista


Quiero cambiar a WKWebView de UIWebView. En mi código, la instancia de la vista web se crea fuera de la pantalla (sin asociarla a la jerarquía de vistas) y se carga la URL. Cuando se realiza la carga, la vista web se presenta al usuario en una ventana UI separada (como un anuncio intersticial). Todo funciona bien con UIWebView; pero después de cambiar a WKWebView, el código angular javascript se comporta de forma inesperada.

Después de investigar un poco, me he dado cuenta de que los temporizadores javascript (y los cargadores HTTP) están suspendidos cuando el WKWebView instancia no está adjunta a la jerarquía de vista: si inicia un temporizador en javascript que se ejecuta en separado WKWebView - No se disparará hasta que se adjunte la vista web.

¿Alguien puede sugerir una posible solución alternativa (además de adjuntar una vista web oculta a la ventana clave y luego moverla a otra ventana)?

Creé un proyecto de muestra para demostrar el problema (o, más probablemente, una función de WebKit)

https://dl.dropboxusercontent.com/u/148568148/WebKitViewTest.zip

La aplicación de prueba carga una página web con javascript que programa un temporizador y carga una solicitud HTTP. Puede usar los interruptores para mostrar / ocultar la vista web (establece la propiedad "oculta") y adjuntar / separar de la jerarquía de la vista.

Sample app running on iOS 8.0

Si la vista web está adjunta (oculta o visible) y usted golpea Load, el javascript funciona bien: puedes ver success o failure diálogo de alerta. Si está desconectado, el temporizador solo se activará cuando esté conectado a la jerarquía de visualización (cambie "Desactivado" a "activado", presione "Cargar", espere unos segundos y vuelva a "apagado"). También puedes consultar console.log de Safari Web Inspector.

Aquí está la fuente de la página web de prueba:

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

Y el 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;
  };
}]);

32
2017-07-01 19:20


origen


Respuestas:


Habiendo tropezado con el mismo problema, nunca encontré ninguna solución excepto para agregar WKWebView a la jerarquía de vistas y moverlo fuera de pantalla con AutoLayout. Afortunadamente, esta solución alternativa funciona de manera confiable.


1
2018-03-18 17:08