Phonegap/Cordova, iOS y los iframes
Es muy posible que todos hayáis tenido la necesidad de incluir un iframe en vuestra aplicación porque queréis mostrar el contenido HTML de una determinada URL. Suponiendo que no queréis utilizar JQuery o cualquier otra solución similar para realizar esta tarea (porque queréis que se pueda navegar dentro del iframe), podéis llegar a tener el mismo dilema que yo.
Utilizando Cordova 2.0.0 en iOS 5.1 con la configuración por defecto, cuando creo un iframe, la URL se abre en Safari. Resulta que en este caso yo quiero que se abra en mi propia aplicación. Pues para solucionar esto basta con cambiar el valor de la propiedad OpenAllWhitelistURLsInWebView, en el fichero Cordova.plist, a YES.
Muy bien esto funciona, pero resulta que además quiero añadir un enlace que permita al usuario abrir el contenido en el navegador por defecto del dispositivo. Buahhh eso es una chorrada ¿verdad?, usas la propiedad target="_blank" en el enlace. Pues no, porque al activar la propiedad OpenAllWhitelistURLsInWebView hemos provocado que esto no funcione, y ¿como lo solucionamos? ... pues no lo tengo claro :-(
Utilizando Objective-C se puede lograr un comportamiento similar al deseado, pero con algunos comportamientos laterales no tan deseados. En el fichero MainViewController.m podemos añadir un nuevo método webView que modifique al comportamiento por defecto cuando se activa un enlace, como nos propone mwbrooks en este Gist.
El problema es que cuando se hace click en alguno de los enlaces contenidos en el iframe se abre en el Safari, esto se debe a que filtramos las URLs por su esquema (http o https), pero tampoco podemos hacer un filtro muy complejo de la URL. Que solución se me ocurre a mi, pues añadir argumentos a la URL como por ejemplo ?MyApp=true y buscarlo en el método webView que hemos modificado. Esto no modifica el correcto funcionamiento en Android y hace que todo funcione bien en iOS, pero no es muy ortodoxo (aunque si nos saca las castañas del fuego).
Si tenéis este problema o similar ya sabéis como lo he enfocado yo por el momento, si encuentro soluciones mejores actualizaré la entrada :-D
Utilizando Cordova 2.0.0 en iOS 5.1 con la configuración por defecto, cuando creo un iframe, la URL se abre en Safari. Resulta que en este caso yo quiero que se abra en mi propia aplicación. Pues para solucionar esto basta con cambiar el valor de la propiedad OpenAllWhitelistURLsInWebView, en el fichero Cordova.plist, a YES.
Muy bien esto funciona, pero resulta que además quiero añadir un enlace que permita al usuario abrir el contenido en el navegador por defecto del dispositivo. Buahhh eso es una chorrada ¿verdad?, usas la propiedad target="_blank" en el enlace. Pues no, porque al activar la propiedad OpenAllWhitelistURLsInWebView hemos provocado que esto no funcione, y ¿como lo solucionamos? ... pues no lo tengo claro :-(
Utilizando Objective-C se puede lograr un comportamiento similar al deseado, pero con algunos comportamientos laterales no tan deseados. En el fichero MainViewController.m podemos añadir un nuevo método webView que modifique al comportamiento por defecto cuando se activa un enlace, como nos propone mwbrooks en este Gist.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Note: the following function should already exist in your application delegate file. | |
* Replace it with the following implementation. | |
* | |
* Thanks to @purplecabbage for implementation. | |
* Thanks to Ruddiger for the iFrame patch. | |
*/ | |
// ... | |
/** | |
* Start Loading Request | |
* This is where most of the magic happens... We take the request(s) and process the response. | |
* From here we can re direct links and other protocalls to different internal methods. | |
*/ | |
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType | |
{ | |
NSURL *url = [request URL]; | |
// Intercept the external http requests and forward to Safari.app | |
// Otherwise forward to the PhoneGap WebView | |
// Avoid opening iFrame URLs in Safari by inspecting the `navigationType` | |
if (navigationType == UIWebViewNavigationTypeLinkClicked && [[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) { | |
[[UIApplication sharedApplication] openURL:url]; | |
return NO; | |
} | |
else { | |
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ]; | |
} | |
} |
El problema es que cuando se hace click en alguno de los enlaces contenidos en el iframe se abre en el Safari, esto se debe a que filtramos las URLs por su esquema (http o https), pero tampoco podemos hacer un filtro muy complejo de la URL. Que solución se me ocurre a mi, pues añadir argumentos a la URL como por ejemplo ?MyApp=true y buscarlo en el método webView que hemos modificado. Esto no modifica el correcto funcionamiento en Android y hace que todo funcione bien en iOS, pero no es muy ortodoxo (aunque si nos saca las castañas del fuego).
Si tenéis este problema o similar ya sabéis como lo he enfocado yo por el momento, si encuentro soluciones mejores actualizaré la entrada :-D
Comentarios