iOS JavaScript桥梁
我正在开发一个应用程序,在这个应用程序中我将同时使用UIWebView中的HTML5和本机iOS框架。 我知道我可以实现JavaScript和Objective-C之间的通信。 有没有任何图书馆简化实施这种沟通? 我知道有几个库可以在HTML5和JavaScript(例如AppMobi,PhoneGap)中创build本机iOS应用程序,但我不确定是否有一个库可以帮助创build具有JavaScript使用量的本机iOS应用程序。 我需要:
- 从Objective-C执行JS方法
- 从JS执行Objective-C方法
- 听从Objective-C的本地JS事件(例如DOM就绪事件)
有几个图书馆,但是我没有在大型项目中使用这些图书馆,所以你可能想试试它们:
- WebViewJavascriptBridge: https : //github.com/marcuswestin/WebViewJavascriptBridge
- GAJavaScript: https : //github.com/newyankeecodeshop/GAJavaScript
–
不过,我觉得这很简单,你可以试一试。 当我需要的时候,我亲自做了这个。 您也可以创build一个适合您需求的简单库。
1.从Objective-C执行JS方法
这实际上只是一行代码。
NSString *returnvalue = [webView stringByEvaluatingJavaScriptFromString:@"your javascript code string here"];
关于官方UIWebView文档的更多细节。
2.从JS执行Objective-C方法
不幸的是,这稍微复杂一点,因为Mac OSX上不存在相同的windowScriptObject属性(和类),允许在两者之间进行完整的通信。
不过,您可以轻松地从JavaScript定制的URL调用,如:
window.location = yourscheme://callfunction/parameter1/parameter2?parameter3=value
从Objective-C中截取它:
- (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 } }
这并不像应该的那样干净(或者使用windowScriptObject),但是它可以工作。
3.听从Objective-C的本地JS事件(例如DOM就绪事件)
从上面的解释可以看出,如果你想这样做,你必须创build一些JavaScript代码,将它附加到你想要监视的事件,并调用正确的window.location
调用来被拦截。
再次,不应该干净,但它的工作原理。
不build议在接受的答案中从JS调用Objective C的build议方法。 问题的一个例子:如果你连续两次打电话,一个会被忽略(你不能快速改变位置)。
我推荐以下替代方法:
function execute(url) { var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", url); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; }
您可以反复调用execute
函数,并且由于每个调用都在其自己的iframe中执行,所以在快速调用时不应忽略它们。
感谢这个家伙 。
更新:这已在iOS 8中更改。我的答案适用于以前的版本。
另一种可能会让你从app store被拒绝的方法是使用WebScriptObject。
这些API在OSX上公开,但不在iOS上。
您需要定义内部类的接口。
@interface WebScriptObject: NSObject @end @interface WebView - (WebScriptObject *)windowScriptObject; @end @interface UIWebDocumentView: UIView - (WebView *)webView; @end
您需要定义将用作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
现在将该实例设置为您的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"]; } } }
现在你的javascript里面可以调用:
yourBridge.someEvent(100, "hello"); yourBridge.testfoo();
在iOS8中,您可以查看WKWebView而不是UIWebView 。 它具有以下类:WKScriptMessageHandler:提供了一种从网页中运行的JavaScript接收消息的方法。
你最好的select是Appcelerators Titanium产品。 他们已经使用webkit使用的V8引擎 JavascriptCore引擎构build了一个Obj-C javascript桥接器。 它也是开源的,所以你可以随意下载和修改Obj-C。
看看KirinJS项目: 麒麟JS允许使用Javascript的应用程序逻辑和本地用户界面足以运行的平台。
我创build了一个类似于WebViewJavascriptBridge的库,但它更像JQuery,更容易设置,更易于使用。 不依赖于jQuery(尽pipe值得称道,在我写这本书之前我已经知道了WebViewJavascriptBridge的存在),我可能刚刚在潜水之前稍微阻挡了一下。 让我知道你的想法! jockeyjs
如果您在iOS 8上使用WKWebView,请查看XWebView ,它可以自动将本机界面公开给JavaScript。