and*_*111 99 javascript html5 uiwebview ios
我正在开发一个应用程序,我将在UIWebView和本机iOS框架中同时使用HTML5.我知道我可以实现JavaScript和Objective-C之间的通信.是否有任何库可以简化实现此通信?我知道有几个库可以在HTML5和javascript中创建本机iOS应用程序(例如AppMobi,PhoneGap),但我不确定是否有一个库来帮助创建使用大量JavaScript的原生iOS应用程序.我需要:
小智 149
有一些库,但我没有在大项目中使用任何这些库,所以你可能想尝试一下:
-
但是,我觉得这很简单,你可以自己尝试一下.当我需要这样做时,我个人就是这样做的.您还可以创建一个适合您需求的简单库.
这只是一行代码.
NSString *returnvalue = [webView stringByEvaluatingJavaScriptFromString:@"your javascript code string here"];
Run Code Online (Sandbox Code Playgroud)
有关官方UIWebView文档的更多详细信息.
遗憾的是,这有点复杂,因为Mac OSX上不存在相同的windowScriptObject属性(和类),允许两者之间的完全通信.
但是,您可以通过javascript自定义URL轻松调用,例如:
window.location = yourscheme://callfunction/parameter1/parameter2?parameter3=value
Run Code Online (Sandbox Code Playgroud)
并使用以下方法从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
}
}
Run Code Online (Sandbox Code Playgroud)
这不是它应该是干净的(或通过使用windowScriptObject),但它的工作原理.
从上面的解释中,您可以看到,如果您想这样做,您必须创建一些JavaScript代码,将其附加到您要监视的事件并调用正确的window.location调用然后被截获.
再次,不应该干净,但它的工作原理.
tal*_*kol 57
建议不要在接受的答案中使用JS调用目标c的建议方法.问题的一个例子:如果你进行两次立即连续调用,则忽略一次(你不能太快地改变位置).
我推荐以下替代方法:
function execute(url)
{
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
Run Code Online (Sandbox Code Playgroud)
您execute重复调用该函数,并且由于每个调用都在其自己的iframe中执行,因此在快速调用时不应忽略它们.
这个家伙的功劳.
Jos*_*nox 12
更新: iOS 8中已更改.我的答案适用于以前的版本.
另一种可能会让您从应用商店中被拒绝的替代方法是使用WebScriptObject.
这些API在OSX上是公开的,但不在iOS上.
您需要定义内部类的接口.
@interface WebScriptObject: NSObject
@end
@interface WebView
- (WebScriptObject *)windowScriptObject;
@end
@interface UIWebDocumentView: UIView
- (WebView *)webView;
@end
Run Code Online (Sandbox Code Playgroud)
您需要定义将用作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
Run Code Online (Sandbox Code Playgroud)
现在将实例设置为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"];
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在你的javascript里面可以调用:
yourBridge.someEvent(100, "hello");
yourBridge.testfoo();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
107021 次 |
| 最近记录: |