如果无法访问UIWebView的运行时,为什么要在iOS7中使用JavaScriptCore?

时间:2013-09-20 15:31:33

标签: ios7 javascriptcore

这是对此博客的回应:

http://blog.bignerdranch.com/3784-javascriptcore-and-ios-7/

来自iOS开发者的想法SO?

5 个答案:

答案 0 :(得分:25)

您可以使用关键路径从UIWebView获取JSContext:

UIWebView *webView = [[UIWebView alloc] init];
JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"document"][@"body"][@"style"][@"background"] = @"steelblue";

Apple从来没有记录任何新的JavaScriptCore API,所以我不确定这是否算作内部/未记录的API。我已批准使用此方法的应用。

更新https://github.com/TomSwift/UIWebView-TS_JavaScriptContext建议的另一个替代解决方案是在NSObject上创建一个类别,并使用它来实现WebKit记录的didCreateJavaScriptContext委托回调。要解释该实现,您只需调用[NSObject contextForWebView:myWebView]来获取UIWebView的JSContext:

@implementation NSObject(JSContextTracker)

+ (NSMapTable *)JSContextTrackerMap {
    static NSMapTable *contextTracker;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        contextTracker = [NSMapTable strongToWeakObjectsMapTable];
    });
    return contextTracker;
}

- (void)webView:(id)unused didCreateJavaScriptContext:(JSContext *)ctx forFrame:(id)alsoUnused {
    NSAssert([ctx isKindOfClass:[JSContext class]], @"bad context");
    if (!ctx)
        return;
    NSMapTable *map = [NSObject JSContextTrackerMap];
    static long contexts = 0;
    NSString *contextKey = [NSString stringWithFormat:@"jsctx_%@", @(contexts++)];
    [map setObject:ctx forKey:contextKey];
    ctx[@"JSContextTrackerMapKey"] = contextKey; // store the key to the map in the context itself
}

+ (JSContext *)contextForWebView:(UIWebView *)webView {
    // this will trigger didCreateJavaScriptContext if it hasn't already been called
    NSString *contextKey = [webView stringByEvaluatingJavaScriptFromString:@"JSContextTrackerMapKey"];
    JSContext *ctx = [[NSObject JSContextTrackerMap] objectForKey:contextKey];
    return ctx;
}

@end

答案 1 :(得分:8)

我想出了一种方法来获得与KVC方法不同的UIWebView JSContext

基本上,通过了解WebKit的一些细节,我们可以在NSObject上实现一个委托回调方法,并在创建时传递JSContext。详情如下:

https://github.com/TomSwift/UIWebView-TS_JavaScriptContext

答案 2 :(得分:5)

在运行应用程序内部运行非与Web相关的JavaScript时非常有用。想想你是否有一堆用JavaScript编写的现有代码,你不想重写?您可以在没有UIWebView的情况下使用JavaScriptCore在您的流程中托管该代码。我还可以想象它被用于为iOS应用程序添加用户脚本。可能性无穷无尽!

另一件值得一提的是UIWebView 非常资源匮乏(毕竟,就像在你的过程中运行Safari的副本一样);它分配了一个你永远不会回来的TON内存。如果您不特别需要Web渲染,JavaScriptCore可以使用更少的资源做很多事情。有关UIWebView资源消耗的详细信息,请参阅my answer over here

答案 3 :(得分:3)

您可以在JavaScript中实现应用程序逻辑,并在iOS和其他平台上使用JS代码。这减少了在iOS,Android,Web等上支持应用程序的工作。

Calatrava是围绕这个想法的框架。

答案 4 :(得分:-3)

您可以使用JavaScript编写ios7应用程序:

http://www.youtube.com/watch?v=y-nodF6Cp1Y