[英]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.