2010-05-29 17 views
8

Im tratando de pasar varias cosas desde una página web dentro de un UIWebView a mi aplicación de iPhone a través del método shouldStartLoadWithRequest de UIWebView.Disparar shouldStartLoadWithRequest con múltiples llamadas a window.location.href

Básicamente mi página web llama a window.location.href = "command: // foo = bar" y soy capaz de interceptar eso en mi aplicación sin problema. Ahora bien, si creo un bucle y hago varias llamadas a window.location.href a la vez, entonces shouldStartLoadWithRequest solo aparece para llamar una vez y la llamada que recibe es la última activación de window.location.href al final del ciclo.

Lo mismo ocurre con la vista web para Android, solo se procesa la última window.location.href.

+0

Encontré una solución inteligente. Cree dinámicamente un iframe para cada comando y configure su src en "command: // foo = bar", puede desconectarlo varias veces en un bucle y shouldStartLoadWithRequest se llamará cada vez. Ahora para estudiar cómo optimizar esto. No creo que sería bueno crear miles de iframes (aunque estén ocultos). Alguna sugerencia sobre eso? – AlBeebe

+0

Intentaría optimizar todas las llamadas de ubicación también. Si solo puede enviar 60 llamadas por minuto, asegúrese de bloquear cada llamada con suficientes variables y fragmentos de consulta para manejar varios comandos por llamada. Además, es posible que desee comprobar wkWebView: http://nshipster.com/wkwebkit/ automatiza gran parte de este proceso y es más confiable. – newshorts

Respuesta

39
iFrame = document.createElement("IFRAME"); 
iFrame.setAttribute("src", "command://foo=bar"); 
document.body.appendChild(iFrame); 
iFrame.parentNode.removeChild(iFrame); 
iFrame = null; 

Así que esto crea un iframe, fija su fuente a un im comando tratando de pasar a la aplicación, a continuación, tan pronto como su adjunto a la shouldStartLoadWithRequest cuerpo se llama, entonces quitamos el marco flotante del cuerpo, y establézcalo en nulo para liberar la memoria.

¡También probé esto en una vista web de Android usando shouldOverrideUrlLoading y también funcionó correctamente!

+3

Esta solución es terriblemente fea, pero parece ser la menos horrible y fea posible. Parece que Javascript "optimiza" al ignorar las llamadas a las ventanas. Las llamadas que luego son reemplazadas por otras llamadas a la ventana. ¡Gracias por salvarme de una sesión de depuración muy dolorosa! – Arkaaito

+0

@Arkaaito +1 por lo horriblemente feo, estoy totalmente de acuerdo – AlBeebe

+4

Quiero hacer un seguimiento ya que publiqué esto hace 2 años. Escribí una aplicación de Android y iPhone que básicamente era una vista web envuelta en una aplicación nativa. Usé esta solución para poder comunicarme desde la vista web a la aplicación nativa y funcionó sin problemas durante los últimos 2 años he tenido más de 500k + descargas de mi aplicación. – AlBeebe

0

No, el cambio de URL de iframe no activará shouldOverrideUrlLoading, al menos no en Android 2.2.

3

También solucioné este problema y aquí está mi solución que funciona para mí. Todas mis funciones de JavaScript usan esta función __js2oc (msg) para pasar los datos y eventos a Objective-C a través de shouldStartLoadWithRequest: P.S. reemplace "command:" con su "appname:" trigger que usa.

/* iPhone JS2Objective-C bridge interface */ 
var __js2oc_wait = 300; // min delay between calls in milliseconds 
var __prev_t = 0; 
function __js2oc(m) { 
    // It's a VERY NARROW Bridge so traffic must be throttled 
    var __now = new Date(); 
    var __curr_t = __now.getTime(); 
    var __diff_t = __curr_t - __prev_t; 
    if (__diff_t > __js2oc_wait) { 
    __prev_t = __curr_t; 
    window.location.href = "command:" + m; 
    } else { 
    __prev_t = __curr_t + __js2oc_wait - __diff_t; 
    setTimeout(function() { 
     window.location.href = "command:" + m; 
    }, (__js2oc_wait - __diff_t)); 
    } 
} 
Cuestiones relacionadas