This is in response to this blog:
http://blog.bignerdranch.com/3784-javascriptcore-and-ios-7/
Thoughts from the iOS devs on SO?
This is in response to this blog:
http://blog.bignerdranch.com/3784-javascriptcore-and-ios-7/
Thoughts from the iOS devs on SO?
You can get a JSContext from a UIWebView with a key path:
UIWebView *webView = [[UIWebView alloc] init];
JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"document"][@"body"][@"style"][@"background"] = @"steelblue";
Apple never got around to documenting any of the new JavaScriptCore APIs, so I'm not sure if this counts as an internal/undocumented API or not. I have an app approved that uses this method.
Update: Another alternative solution suggested at https://github.com/TomSwift/UIWebView-TS_JavaScriptContext is to make a category on NSObject
and use it to implement WebKit's documented didCreateJavaScriptContext
delegate callback. To paraphrase that implementation, you can just call [NSObject contextForWebView:myWebView]
to grab the JSContext for a UIWebView:
@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
_documentView
getter in the runtime headers, but I'm curious how anyone dug further than that. –
Kauri I came up with an approach to get the UIWebView
JSContext
that is different from the KVC approach.
Basically, by knowing some details about WebKit, we can implement a delegate callback method on NSObject and be handed the JSContext when it is created. Details here:
It'd be useful for running non-web-related JavaScript hosted inside your application. Think about if you had a bunch of existing code written in JavaScript that you didn't want to re-write? You can use JavaScriptCore without a UIWebView to host that code in your process. I can also imagine it being used to add user-scriptability to iOS apps. The possibilities are endless!
The other thing worth mentioning here is that UIWebView is very resource-hungry (after all, it's like running a copy of Safari in your process); It allocates a TON of memory that you will simply never get back. If you don't specifically need web rendering, JavaScriptCore can do a lot with a lot fewer resources. See my answer over here for details about UIWebView's resource consumption.
You can implement application logic in JavaScript and used the JS code on iOS and other platforms. This cuts down the work of supporting an app on iOS, Android, Web, etc.
Calatrava is a framework around this idea.
You can write ios7 apps using JavaScript:
© 2022 - 2024 — McMap. All rights reserved.