Parece que no hay un método oficial para hacerlo. Sin embargo, thestandardworkaround implica leer y analizar las solicitudes de URL entrantes, básicamente con su propio protocolo de mensajería serializada. El manejo de mensajes debe hacerse en el método webView:shouldStartLoadWithRequest:navigationType
de su controlador de vista.
Nota: hay varias bibliotecas libres (PhoneGap, QuickConnect, JS-to-Cocoa Bridge) que envuelven esta funcionalidad (además de hacer mucho más). Para reinventar la rueda (o saber por qué es redonda, por así decirlo), sigue leyendo.
Desde JavaScript, invocará la devolución de llamada al tratar de navegar a una nueva URL:
// In JavaScript
window.location = 'myapp:myaction:param1:param2'; // etc...
En Objective-C, aplicar el protocolo UIWebViewDelegate
en su archivo .h
:
// In your header file
@interface MyAppViewController : UIViewController <UIWebViewDelegate> {
...
}
@end
A continuación, implemente el método en su archivo .m
:
// In your implementation file
-(BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
// Break apart request URL
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@":"];
// Check for your protocol
if ([components count] > 1 &&
[(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"])
{
// Look for specific actions
if ([(NSString *)[components objectAtIndex:1] isEqualToString:@"myaction"])
{
// Your parameters can be found at
// [components objectAtIndex:n]
// where 'n' is the ordinal position of the colon-delimited parameter
}
// Return 'NO' to prevent navigation
return NO;
}
// Return 'YES', navigate to requested URL as normal
return YES;
}
Dos notas importantes:
Contexto: navegar a myapp:whatever
será (por supuesto) fallar en cualquier otro contexto. Tenga esto en cuenta si está cargando páginas multiplataforma.
sincronización: si un segundo window.location =
llamada se realiza antes de las primeras vueltas, se pondrá 'perdido'. Por lo tanto, agrupe sus llamadas, demore la ejecución manualmente o implemente una cola que combine lo anterior con JS queries into Objective-C objects.
simplemente me encontré con una pregunta más antigua preguntando lo mismo: http://stackoverflow.com/questions/1662473/how-to-call-objective-c-from-javascript. Mi respuesta a continuación da la misma solución ... –
Este es un truco ingenioso, pero se puede encontrar una técnica mejor [aquí] [1]. [1]: http://stackoverflow.com/questions/1662473/how-to-call-objective-c-from-javascript –