Je travaille sur une application où je vais utiliser à la fois HTML5 dans UIWebView et le framework iOS natif. Je sais que je peux implémenter la communication entre JavaScript et Objective-C. Existe-t-il des bibliothèques qui simplifient la mise en œuvre de cette communication? Je sais qu'il existe plusieurs bibliothèques pour créer des applications iOS natives en HTML5 et en javascript (par exemple, AppMobi, PhoneGap), mais je ne suis pas sûr s'il existe une bibliothèque permettant de créer des applications iOS natives avec une utilisation intensive de JavaScript. J'ai besoin de:
Il y a quelques bibliothèques, mais je ne les ai pas utilisées dans de grands projets. Vous voudrez peut-être les essayer:
-
Cependant, je pense que c'est quelque chose d'assez simple pour que vous puissiez l'essayer vous-même. Personnellement, je l'ai fait exactement quand j'avais besoin de le faire. Vous pouvez également créer une bibliothèque simple qui répond à vos besoins.
Ce n'est vraiment qu'une ligne de code.
NSString *returnvalue = [webView stringByEvaluatingJavaScriptFromString:@"your javascript code string here"];
Plus de détails sur la documentation officielle UIWebView Documentation .
C'est malheureusement un peu plus complexe, car il n'y a pas la même propriété windowScriptObject (et la même classe) que Mac OSX, ce qui permet une communication complète entre les deux.
Cependant, vous pouvez facilement appeler à partir d'URL personnalisées javascript, telles que:
window.location = yourscheme://callfunction/parameter1/parameter2?parameter3=value
Et l'intercepter d'Objective-C avec ceci:
- (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
}
}
Ce n’est pas aussi propre qu’il devrait l’être (ni en utilisant windowScriptObject), mais cela fonctionne.
D'après l'explication ci-dessus, vous voyez que si vous voulez faire cela, vous devez créer du code JavaScript, le joindre à l'événement que vous souhaitez surveiller et appeler le bon appel window.location
à intercepter.
Encore une fois, pas propre comme il se doit, mais cela fonctionne.
La méthode suggérée pour appeler Objective C depuis JS dans la réponse acceptée n'est pas recommandée. Un exemple de problèmes: si vous effectuez deux appels consécutifs immédiats, l’un est ignoré (vous ne pouvez pas changer d’emplacement trop rapidement).
Je recommande l'approche alternative suivante:
function execute(url)
{
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
Vous appelez la fonction execute
à plusieurs reprises et, chaque appel étant exécuté dans sa propre iframe, ils ne doivent pas être ignorés lorsqu'ils sont appelés rapidement.
Crédits à ce gars .
Mise à jour: Cela a changé dans iOS 8. Ma réponse s'applique aux versions précédentes.
Une alternative, qui peut vous faire rejeter de la boutique d'applications, est d'utiliser WebScriptObject.
Ces API sont publiques sur OSX mais pas sur iOS.
Vous devez définir des interfaces avec les classes internes.
@interface WebScriptObject: NSObject
@end
@interface WebView
- (WebScriptObject *)windowScriptObject;
@end
@interface UIWebDocumentView: UIView
- (WebView *)webView;
@end
Vous devez définir votre objet qui va servir de 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
Maintenant, définissez cette instance sur votre 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"];
}
}
}
Maintenant, à l'intérieur de votre javascript, vous pouvez appeler:
yourBridge.someEvent(100, "hello");
yourBridge.testfoo();
Dans iOS8, vous pouvez regarder WKWebView au lieu de UIWebView . Cela a la classe suivante: WKScriptMessageHandler: fournit une méthode pour recevoir des messages de JavaScript s'exécutant dans une page Web.
C'est possible avec iOS7, checkout http://blog.bignerdranch.com/3784-javascriptcore-and-ios-7/
Jetez un coup d’œil au projet KirinJS: Kirin JS qui permet d’utiliser Javascript pour la logique de l’application et une interface utilisateur native adaptée à la plate-forme sur laquelle il est exécuté.
Si vous utilisez WKWebView sur iOS 8, jetez un coup d'œil à XWebView , qui peut automatiquement exposer l'interface native à JavaScript.
J'ai créé une bibliothèque telle que WebViewJavascriptBridge, mais elle ressemble plus à JQuery, est plus facile à configurer et à utiliser. Ne comptez pas sur jQuery (bien que ce soit un crédit, si j'avais su que WebViewJavascriptBridge existait avant d'écrire cela, je me suis peut-être légèrement retenu avant de plonger). Laissez-moi savoir ce que vous pensez! jockeyjs
Votre meilleur pari est l’offre Appcelerators Titanium. Ils ont déjà construit un pont javascript Obj-C en utilisant le Moteur V8 Moteur JavascriptCore utilisé par webkit. Il est également open source, vous pourrez donc le télécharger et bricoler avec l'Obj-C à votre guise.