14

这是对此博客的回应:

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

iOS 开发人员对 SO 的看法?

4

5 回答 5

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
于 2013-11-19T01:19:37.307 回答
8

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

基本上,通过了解 WebKit 的一些细节,我们可以在 NSObject 上实现一个委托回调方法,并在创建 JSContext 时将其交给它。详情在这里:

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

于 2013-11-22T23:10:15.543 回答
5

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

这里值得一提的另一件事是 UIWebView非常消耗资源(毕竟,这就像在您的进程中运行 Safari 的副本);它分配了大量的内存,您将永远无法取回。如果你不是特别需要 Web 渲染,JavaScriptCore 可以用更少的资源做很多事情。有关 UIWebView 资源消耗的详细信息,请参阅我的答案。

于 2013-09-20T16:33:36.180 回答
3

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

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

于 2013-09-29T12:59:26.697 回答
-3

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

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

于 2013-12-08T14:49:55.263 回答