JavaScriptCore console.log

She*_*tJS 23 javascript macos xcode objective-c core-foundation

我已经整理了一个非常简单的程序,它使用JavaScriptCore来评估JS:

#import <CoreFoundation/CoreFoundation.h>
#import <JavaScriptCore/JavaScriptCore.h>

int main(int argc, const char * argv[])
{
    JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);

    FILE *f = fopen(argv[1],"r");
    char * buffer = malloc(10000000);
    fread(buffer,1,10000000,f);

    CFStringRef strs = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);

    JSStringRef jsstr = JSStringCreateWithCFString(strs);
    JSValueRef result = JSEvaluateScript(ctx, jsstr, NULL, NULL, 0, NULL);

    double res  = JSValueToNumber(ctx, result, NULL);
    JSGlobalContextRelease(ctx);

    printf("%lf\n", res);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是最后一个值应该是a Number,并打印该值.这适用于有效的JavaScript代码,例如

var square = function(x) { return x*x; }; square(4)
Run Code Online (Sandbox Code Playgroud)

但是,如果代码尝试执行a console.log,则程序会出现段错误.JSC中是否有可用的日志功能,还是我必须自己滚动?

Mik*_*ike 24

如果使用Mac或IOS的JavaScriptCore框架,则必须提供自己的控制台日志.

这里有一些代码对我有用(对不起,根据你上面的代码,它是Objective-C而不是标准C):

JSContext *javascriptContext  = [[JSContext alloc] init];
javascriptContext[@"consoleLog"] = ^(NSString *message) {
    NSLog(@"Javascript log: %@",message);
};
Run Code Online (Sandbox Code Playgroud)

然后你从Javascript使用它:

consoleLog("My debug message");
Run Code Online (Sandbox Code Playgroud)

请注意,我已经尝试定义了一个vararg版本(记录了多个参数),但我无法在框架api中正常工作.

请注意,此解决方案使用随新的Objective-C API引入的功能,用于与IOS 7同时引入的JavaScriptCore.framework.如果您正在寻找Objective-C和Javascript之间这个良好集成的桥梁的介绍,请查看2013年WWDC在Apple开发者网络上的"将JavaScript集成到本机应用程序"会议中的介绍:https://developer.apple.com/videos/wwdc/2013/?id = 615

更新回答:

对于那些想要在没有重构的情况下最大化你的javascript代码重用的人,我已经设法得到一个版本工作,它声明了一个console.log()形式的日志:

JSContext *javascriptContext  = [[JSContext alloc] init];
[javascriptContext evaluateScript:@"var console = {}"];
javascriptContext[@"console"][@"log"] = ^(NSString *message) {
    NSLog(@"Javascript log: %@",message);
};
Run Code Online (Sandbox Code Playgroud)

然后你从Javascript使用它:

console.log("My debug message");
Run Code Online (Sandbox Code Playgroud)

  • 我还对该主题进行了一项小型研究http://kalapun.com/blog/2014/03/26/ios-and-javascript-first-try/ (2认同)
  • 您可能还希望看到来自JavaScriptCore的错误。`javascriptContext.exceptionHandler = ^(JSContext * context,JSValue * exception){NSLog(@“ JS错误:%@”,异常); };` (2认同)

AlB*_*ebe 15

Swift 3.0

let javascriptContext = JSContext()
javascriptContext?.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
let consoleLog: @convention(block) (String) -> Void = { message in
    print("console.log: " + message)
}
javascriptContext?.setObject(unsafeBitCast(consoleLog, to: AnyObject.self), forKeyedSubscript: "_consoleLog" as (NSCopying & NSObjectProtocol)!)
Run Code Online (Sandbox Code Playgroud)

斯威夫特2.1

let javascriptContext = JSContext()
javascriptContext.evaluateScript("var console = { log: function(message) { _consoleLog(message) } }")
let consoleLog: @convention(block) String -> Void = { message in
    print("console.log: " + message)
}
javascriptContext.setObject(unsafeBitCast(consoleLog, AnyObject.self), forKeyedSubscript: "_consoleLog")
Run Code Online (Sandbox Code Playgroud)

然后你从Javascript使用它:

console.log("My debug message");
Run Code Online (Sandbox Code Playgroud)


Ant*_*sov 5

self.jsContext = JSContext()
self.jsContext.evaluateScript(...)       
let logFunction: @convention(block) (String) -> Void  = { (string: String) in
    print(string)
}

self.jsContext.setObject(logFunction, forKeyedSubscript: "consoleLog" as NSCopying & NSObjectProtocol)
Run Code Online (Sandbox Code Playgroud)