简体   繁体   English

JavaScriptCore console.log

[英]JavaScriptCore console.log

I've put together a very simple program that uses JavaScriptCore to evaluate JS: 我编写了一个非常简单的程序,该程序使用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;
}

The idea here is that the last value is expected to be a Number , and that value is printed. 这里的想法是,最后一个值应为Number ,并打印该值。 This works for valid javascript code, such as 这适用于有效的JavaScript代码,例如

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

However, if the code tries to perform a console.log , the program segfaults. 但是,如果代码尝试执行console.log ,则程序会出现段错误。 Is there a log function available in JSC or do I have to roll my own? JSC中是否有可用的日志功能,还是我必须自己滚动?

You do have to provide your own console log if using the JavaScriptCore framework from Mac or IOS. 如果使用Mac或IOS的JavaScriptCore框架,则必须提供自己的控制台日志。

Here is some code that worked for me (sorry it is Objective-C rather than standard C as per your code above): 这是一些对我有用的代码(抱歉,上面的代码是Objective-C而不是标准C):

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

Then you use it from Javascript by: 然后,您可以通过以下方式从Javascript使用它:

consoleLog("My debug message");

Note that I have tried to define a vararg version (log taking multiple parameters) but I couldn't get this to work correctly across the framework api. 请注意,我尝试定义vararg版本(采用多个参数的日志),但无法在框架api上正常运行。

Note that this solution uses features introduced with the new Objective-C API for the JavaScriptCore.framework introduced at the same time as IOS 7. If you are looking for an intro to this well-integrated bridge between Objective-C and Javascript, check out the 2013 WWDC introduction "Integrating JavaScript into Native Apps" session on Apple's developer network: https://developer.apple.com/videos/wwdc/2013/?id=615 请注意,此解决方案使用了与iOS 7同时引入的JavaScriptCore.framework的新Objective-C API引入的功能。如果您正在寻找Objective-C和Javascript之间这种良好集成的桥梁的入门,请查看苹果公司开发人员网络上的2013年WWDC简介“将JavaScript集成到本机应用程序中”会议: https : //developer.apple.com/videos/wwdc/2013/?id=615

Update to answer: 更新答案:

For those of you wanting to maximise your javascript code reuse without refactoring, I've managed to get a version working that declares a log of the form console.log() : 对于那些想要最大限度地重用javascript代码而不进行重构的人,我设法获得了一个版本,该版本声明了console.log()形式的日志:

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

Then you use it from Javascript by: 然后,您可以通过以下方式从Javascript使用它:

console.log("My debug message");

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

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

Then you use it from Javascript by: 然后,您可以通过以下方式从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)

You can debug JS file attached to context in Safari. 您可以在Safari中调试附加到上下文的JS文件。

Steps: 脚步:

1) Start Safari 1)启动Safari

2) In Safari, enable the Develop menu by going to "Preferences" -> "Advanced" -> "Show Develop menu in menu bar" 2)在Safari中,通过转到“首选项”->“高级”->“在菜单栏中显示开发菜单”启用“开发”菜单

3) Go to Develop menu -> "Simulator" or name of your computer -> select "Automatically show web inspector for JSContexts" and "Automatically pause connecting to JSContexts" 3)转到“开发”菜单->“模拟器”或您的计算机名称->选择“自动显示JSContexts Web检查器”和“自动暂停连接到JSContexts”

4) Re-run your project and Safari should auto-show the web inspector 4)重新运行您的项目,Safari应该自动显示Web检查器

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

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