2010-01-05 20 views
10

Existe un problema conocido con UIWebViews incrustado que si carga datos en ellos utilizando loadHTMLString o loadData, las propiedades canGoBack/canGoForward y los métodos goBack/goForward no funcionan. Estos solo funcionan cuando se usa loadRequest.El uso de una UIWebView con loadHTMLString/loadData rompe los botones de retroceso y avance, ¿solución alternativa?

Dado que la caché de aplicaciones normal de Safari no funciona en UIWebViews incrustadas, la creación de una aplicación nativa que almacena de manera efectiva el contenido en vivo de otra manera se vuelve imposible/inutilizable. Es decir, puedo almacenar en caché los contenidos de HTML, Javascript, imágenes, etc. y cargarlos a través de loadHTMLString o loadData, pero luego los botones de retroceder y avanzar no funcionan.

También podría usar loadRequest y especificar un archivo URL, pero se rompe cuando se trata de comunicarse con el sitio en vivo, incluso si especifico una etiqueta (debido a problemas con el dominio de cookies).

Tengo un problema que implica básicamente volver a implementar el caché de la aplicación utilizando la tienda local (y no tener la aplicación nativa haciendo caché), lo cual está bien, pero no es realmente ideal. ¿Hay alguna otra solución alternativa/algo que me perdí?

+0

Intente configurar NSMutableArray y recopile las URL usted mismo. –

Respuesta

1

¿Descargue usted mismo el código HTML y páselo a UIWebView como una cadena? ¿Porque? ¿Lo modifica sobre la marcha o algo así?

Tal vez un esquema de URL personalizado ayudaría? Utiliza loadRequest con un esquema propio, que a su vez funciona con HTTP y luego alimenta la vista web con los datos que desee.

+0

Descargo el HTML yo mismo y también descargo un montón de imágenes, css y javascript. Los estoy combinando manualmente, pero eso no es realmente significativo para los problemas que estoy enfrentando. El verdadero problema es que queremos que nuestra aplicación nativa, que es básicamente la aplicación web + algunas mejoras, se cargue lo más rápido posible y confiar en el navegador no es confiable en términos de rendimiento. Aunque estoy familiarizado con esquemas personalizados para iniciar aplicaciones nativas y con el uso de shouldStartLoadWithRequest, no estoy al tanto de cómo usar un esquema personalizado para cargar otros tipos de datos. ¿Sugerencias? Seguiré buscando. –

0

Podría buscar el contenido, guardarlo en el sistema de archivos local, señalar la vista web al sistema de archivos local utilizando file: // URLs, luego interceptar el enlace seguido de shouldStartLoadWithRequest para buscar más en fs locales, señalar webview en local nuevo contenido, etc.?

He tenido buena suerte con UIWebView y file: /// URLs. Básicamente, estarías interceptando solicitudes de carga, obteniendo cosas tú mismo, escribiéndolas en el sistema de archivos local con URL reescritas, y luego cargándolas en el navegador.

Parece que no hay forma de cargar/guardar el historial del navegador.

+0

Eso funciona bien para todo hasta que necesitemos autenticación para trabajar, que hace uso de cookies asociadas con el servidor de dominio normal. Pude interceptar todo esto y básicamente manejar todo yo solo, pero en ese punto, volver a implementar la memoria caché de la aplicación usando la tienda local es simplemente más fácil, de hecho ya lo he hecho (aunque todavía no es ideal). –

+0

Y supongo que tendrá problemas para obtener recursos al costado de la página. La ruta relativa puede señalar a ningún lugar. @Brian, es sobre: ​​el truco en blanco funciona para usted? –

2

Estoy usando el canGoBack de UIWebView para verificar si estoy en la primera página del historial. Si lo estoy, solo llamo al pequeño método que utilicé para cargar la primera página (displayLocalResource configura el HTMLString y lo carga en el webView). Aquí hay un fragmento:

//Implementing a back button 
- (void)backOne:(id)sender{ 
    if ([webView canGoBack]) { 
     // There's a valid webpage to go back to, so go there 
     [webView goBack]; 
    } else { 
     // You've reached the end of the line, so reload your own data 
      [self displayLocalResource]; 
     } 
    } 
+0

Esto no funciona para mí:/displayLocalResource rompe el simulador y canGoBack sigue devolviendo nulo, aunque estoy ejecutando archivos locales. ¿Alguna idea? – Andre

+0

displayLocalResource es la función que haya definido para configurar el HTML y cargarlo en el webView. Tendrás que escribir la función. Creo que canGoBack siempre devolverá NULL hasta que hayas hecho clic en un enlace. Este código está en mi repositorio github bajo OOZWebView. – Walter

+0

Creo que tiene un error. Digamos que aterrizó en el sitio A con displayLocalResource. Luego ve a B, luego ve a C. Luego regresa a B y regresa a A. Luego, si vas hacia adelante, irá directamente a C. B falta. –

0

Cargando la cadena en un archivo temporal y usar eso como una solicitud de URL parece curar esto. Es algo sobre cargar la cadena directamente lo que causa que UIWebView no lo vea como la página de inicio a la que puede navegar. Este código funcionó para mí:

//If you load the string like this, then "webView.canGoBack" never returns YES. It's documented frequently on the web. 
//Loading the string as a URL instead seems to work better. 
//[self.myWebView loadHTMLString:str baseURL:nil]; 

//write the string to a temp file 
NSString *fileName = @"homepage.html"; 
NSURL *fileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]]; 
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; 
[data writeToURL:fileURL atomically:NO]; 

//open that temp file in the UIWebView 
[self.myWebView loadRequest:[NSURLRequest requestWithURL:fileURL]]; 

Utilice esta opción para activar/desactivar el botón de retroceso:

- (void)webViewDidFinishLoad:(UIWebView *)webView{ 
    //this is to check if we're back at the root page. 
    if (webView.canGoBack == YES) { 
     self.backButton.enabled=YES; 
    } 
    else { 
     self.backButton.enabled=NO; 
    } 
} 
+1

¿No usar una URL local romperá la descarga relativa de recursos en la página? –

0

que tenían un mismo problema. Intenté administrar el historial, pero es propenso a errores. Ahora he descubierto una mejor solución de esto.

Lo que quiere hacer es simplemente agregar un loadRequest a about: blank y hacer eso como un marcador de posición antes de llamar a loadHTMLString/loadData. Entonces estás totalmente libre de monitorear la historia. El webview.canGoBack y canGoForward funcionarán. Por supuesto, necesitará un truco para manejar volver al marcador de posición sobre: ​​en blanco. Puedes hacer eso en webViewDidFinishLoad.Aquí es el punto culminante código:

En la función cuando se llama loadHTMLString:

[weakSelf.fbWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]]; 
[weakSelf.fbWebView loadHTMLString:stringResponse baseURL:url]; 

Código de manejar goBack:

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    if ([webView.request.URL.absoluteString isEqualToString:@"about:blank"] 
     && ![webView canGoBack] && [webView canGoForward]) { 
    [weakSelf.fbWebView loadHTMLString:stringResponse baseURL:url]; 
    } 
} 

Creo que también es posible ampliar esta solución para manejar los loadHTMLString esa no es la primera carga Solo con tener una Pila para registrar toda la respuesta de cadena e insertar un sobre: ​​en blanco en cada loadHTMLString. Y haga estallar la pila cada vez que vuelva a estar en blanco: en blanco.

Cuestiones relacionadas