繁体   English   中英

JavaScriptCore console.log

[英]JavaScriptCore console.log

我编写了一个非常简单的程序,该程序使用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;
}

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

var square = function(x) { return x*x; }; square(4)

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

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

这是一些对我有用的代码(抱歉,上面的代码是Objective-C而不是标准C):

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

然后,您可以通过以下方式从Javascript使用它:

consoleLog("My debug message");

请注意,我尝试定义vararg版本(采用多个参数的日志),但无法在框架api上正常运行。

请注意,此解决方案使用了与iOS 7同时引入的JavaScriptCore.framework的新Objective-C API引入的功能。如果您正在寻找Objective-C和Javascript之间这种良好集成的桥梁的入门,请查看苹果公司开发人员网络上的2013年WWDC简介“将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);
};

然后,您可以通过以下方式从Javascript使用它:

console.log("My debug message");

斯威夫特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)!)

斯威夫特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")

然后,您可以通过以下方式从Javascript使用它:

console.log("My debug message");
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)

您可以在Safari中调试附加到上下文的JS文件。

脚步:

1)启动Safari

2)在Safari中,通过转到“首选项”->“高级”->“在菜单栏中显示开发菜单”启用“开发”菜单

3)转到“开发”菜单->“模拟器”或您的计算机名称->选择“自动显示JSContexts Web检查器”和“自动暂停连接到JSContexts”

4)重新运行您的项目,Safari应该自动显示Web检查器

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM