javascript - español - instalar framework 7
Puente JavaScript de iOS (9)
Estoy trabajando en una aplicación en la que utilizaré tanto HTML5 en UIWebView como el marco iOS nativo. Sé que puedo implementar la comunicación entre JavaScript y Objective-C. ¿Hay bibliotecas que simplifiquen la implementación de esta comunicación? Sé que hay varias bibliotecas para crear aplicaciones nativas de iOS en HTML5 y JavaScript (por ejemplo, AppMobi, PhoneGap), pero no estoy seguro de si hay una biblioteca que ayude a crear aplicaciones nativas de iOS con un uso intensivo de JavaScript. Necesito:
- Ejecutar métodos JS desde Objective-C
- Ejecutar métodos Objective-C de JS
- Escuchar eventos JS nativos desde Objective-C (por ejemplo, evento DOM ready)
Creé una biblioteca como WebViewJavascriptBridge, pero es más similar a JQuery, tiene una configuración más fácil y es más fácil de usar. No confía en jQuery (aunque a su favor, si hubiera sabido que existía WebViewJavascriptBridge antes de escribir esto, es posible que me haya limitado un poco antes de meterme). ¡Déjame saber lo que piensas! jockeyjs
Eche un vistazo al proyecto KirinJS: Kirin JS que permite usar Javascript para la lógica de la aplicación y la IU nativa adecuada para la plataforma en la que se ejecuta.
Esto es posible con iOS7, checkout http://blog.bignerdranch.com/3784-javascriptcore-and-ios-7/
Hay algunas bibliotecas, pero no las utilicé en grandes proyectos, por lo que es posible que desee probarlas:
- WebViewJavascriptBridge: https://github.com/marcuswestin/WebViewJavascriptBridge
- GAJavaScript: https://github.com/newyankeecodeshop/GAJavaScript
-
Sin embargo, creo que es algo tan simple que podrías intentarlo tú mismo. Personalmente hice exactamente esto cuando necesité hacer eso. También puede crear una biblioteca simple que se adapte a sus necesidades.
1. Ejecutar métodos JS desde Objective-C
Esto es realmente solo una línea de código.
NSString *returnvalue = [webView stringByEvaluatingJavaScriptFromString:@"your javascript code string here"];
Más detalles sobre la documentación oficial de UIWebView .
2. Ejecutar métodos Objective-C de JS
Desafortunadamente, esto es un poco más complejo, porque no existe la misma propiedad WindowScriptObject (y clase) que existe en Mac OSX que permite la comunicación completa entre los dos.
Sin embargo, puede llamar fácilmente desde URL personalizadas de JavaScript, como:
window.location = yourscheme://callfunction/parameter1/parameter2?parameter3=value
E interceptarlo de Objective-C con esto:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *URL = [request URL];
if ([[URL scheme] isEqualToString:@"yourscheme"]) {
// parse the rest of the URL object and execute functions
}
}
Esto no es tan limpio como debería (o usando windowScriptObject) pero funciona.
3. Escuchar eventos JS nativos desde Objective-C (por ejemplo, evento listo para DOM)
A partir de la explicación anterior, verá que si desea hacer eso, debe crear un código JavaScript, adjuntarlo al evento que desea monitorear y llamar a la llamada de window.location
correcta para ser interceptado.
De nuevo, no está limpio como debería ser, pero funciona.
No se recomienda el método sugerido para llamar al objetivo c de JS en la respuesta aceptada. Un ejemplo de problemas: si realiza dos llamadas consecutivas inmediatas, se ignorará una (no puede cambiar la ubicación demasiado rápido).
Recomiendo el siguiente enfoque alternativo:
function execute(url)
{
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
Llama a la función de execute
repetidamente y dado que cada llamada se ejecuta en su propio iframe, no se deben ignorar cuando se llama rápidamente.
Créditos para este tipo .
Si está utilizando WKWebView en iOS 8, eche un vistazo a XWebView que puede exponer automáticamente la interfaz nativa a javascript.
Su mejor apuesta es la oferta de aceleradores de titanio. Ya han construido un puente JavaScript de Obj-C usando el motor JavascriptCore del motor V8 utilizado por webkit. También es de código abierto, por lo que podrás descargarlo y jugar con Obj-C a tu gusto.
En iOS8 puedes mirar WKWebView en lugar de UIWebView . Tiene la siguiente clase: WKScriptMessageHandler: proporciona un método para recibir mensajes de JavaScript ejecutándose en una página web.
Actualización: Esto ha cambiado en iOS 8. Mi respuesta se aplica a versiones anteriores.
Una alternativa, que puede hacer que te rechacen desde la tienda de aplicaciones, es usar WebScriptObject.
Estas API son públicas en OSX pero no en iOS.
Necesita definir interfaces para las clases internas.
@interface WebScriptObject: NSObject
@end
@interface WebView
- (WebScriptObject *)windowScriptObject;
@end
@interface UIWebDocumentView: UIView
- (WebView *)webView;
@end
Necesita definir su objeto que servirá como su WebScriptObject
@interface WebScriptBridge: NSObject
- (void)someEvent: (uint64_t)foo :(NSString *)bar;
- (void)testfoo;
+ (BOOL)isKeyExcludedFromWebScript:(const char *)name;
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector;
+ (WebScriptBridge*)getWebScriptBridge;
@end
static WebScriptBridge *gWebScriptBridge = nil;
@implementation WebScriptBridge
- (void)someEvent: (uint64_t)foo :(NSString *)bar
{
NSLog(bar);
}
-(void)testfoo {
NSLog(@"testfoo!");
}
+ (BOOL)isKeyExcludedFromWebScript:(const char *)name;
{
return NO;
}
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector;
{
return NO;
}
+ (NSString *)webScriptNameForSelector:(SEL)sel
{
// Naming rules can be found at: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/WebKit/Protocols/WebScripting_Protocol/Reference/Reference.html
if (sel == @selector(testfoo)) return @"testfoo";
if (sel == @selector(someEvent::)) return @"someEvent";
return nil;
}
+ (WebScriptBridge*)getWebScriptBridge {
if (gWebScriptBridge == nil)
gWebScriptBridge = [WebScriptBridge new];
return gWebScriptBridge;
}
@end
Ahora configura esa instancia en tu UIWebView
if ([uiWebView.subviews count] > 0) {
UIView *scrollView = uiWebView.subviews[0];
for (UIView *childView in scrollView.subviews) {
if ([childView isKindOfClass:[UIWebDocumentView class]]) {
UIWebDocumentView *documentView = (UIWebDocumentView *)childView;
WebScriptObject *wso = documentView.webView.windowScriptObject;
[wso setValue:[WebScriptBridge getWebScriptBridge] forKey:@"yourBridge"];
}
}
}
Ahora dentro de tu javascript puedes llamar:
yourBridge.someEvent(100, "hello");
yourBridge.testfoo();