最近需要开发一个Cocos Creator Monkey,Cocos Creator里面的内容是使用JavaScript编写的,所以需要获取JavaScript页面。ios在程序内获取javascript页面通常是利用JavaScriptCore(oc与js通信的方式之一)。
一、JavaScriptCore
JavaScriptCore是JavaScript的虚拟机,为JavaScript的执行提供底层资源。对于Safari,CocosCreator支持Safari调试协议,因为在Cocos Creator里面提供了一个JavaScriptCore引擎。
现在使用WebKit的主要两个浏览器Sfari和Chromium(Chorme的开源项目)。WebKit起源于KDE的开源项目Konqueror的分支,由苹果公司用于Sfari浏览器。其一条分支发展成为Chorme的内核,2013年Google在此基础上开发了新的Blink内核。
1、JavaScript引擎
JavaScript引擎是专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。第一个JavaScript引擎由布兰登·艾克在网景公司开发,用于Netscape Navigator网页浏览器中。JavaScriptCore就是一个JavaScript引擎。
2、JavaScriptCore使用
JavaScriptCore是一个C++实现的开源项目。使用Apple提供的JavaScriptCore框架,你可以在Objective-C或者基于C的程序中执行Javascript代码,也可以向JavaScript环境中插入一些自定义的对象。JavaScriptCore从iOS 7.0之后可以直接使用。
//创建虚拟机
JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];
//创建上下文
JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];
//执行JavaScript代码并获取返回值
JSValue *value = [context evaluateScript:@"1+2*3"];
//转换成OC数据并打印
NSLog(@"value = %d", [value toInt32]);
Output
value = 7
二、Cocos Creator远程真机调试JavaScript
参考 官方链接
1、Safari 远程调试 JavaScriptCore(ios)
- 通过 USB 数据线将设备和电脑连接起来。
- 打开 iPhone 的设置 -> Safari -> 高级 -> 打开 Web 检查器。
- 在 Creator 的构建发布面板选择 iOS 平台、Debug 模式,构建工程。在 Xcode 中打开工程。
- 在工程中添加签名:选择你的 iOS 工程 -> General -> Signing -> 选择你的开发者证书。
- 为 Xcode 工程添加 entitlements 文件,如果 entitlements 文件存在则跳过此步骤。如果不存在,则到工程的 Capabilities 设置中打开 iCloud,然后再关闭。这时 .entitlements 文件会被自动添加到工程中。
- 确保 Build Setting 里面 Code Signing Entitlements 选项中包含 entitlements 文件
- 打开 entitlements 文件,手动添加 get-task-allow,值类型为 Boolean,值为 YES。
- 在 Xcode 中编译工程,将工程发布到设备上。
- Safari 菜单中选择 开发 -> 你的设备 -> Cocos2d-x JSB(该步骤如果找不到你的设备,有可能是因为 Safari 版本过低,需要升级 Safari)
- 在弹出的 Web Inspector 中进行调试:
![]()
三、使用JSB进入Cocos Creator的js世界
1、远程调试原理浅析(ios)
Cocos Creator支持远程调试IOS,是因为Cocos Creator里面支持JavaScriptCore引擎,客户端通过Safari调试协议即可远程调试app内的JavaScript。在程序内部要获取JavaScript页面,可以通过CocosCreator提供的JSB进行获取,在ios侧,JSB底层就是封装了一个JavaScriptCore。
2、使用脚本进入Cocos Creator的js世界
在oc中封装调用jsb代码
+ (BOOL)runScript:(NSString*)path {
if(path == nil) {
ABCLogError(@"callJSFunc fail, path is null..");
return NO;
}
if(![NSThread isMainThread]) {
__block bool ret = NO;
dispatch_sync(dispatch_get_main_queue(), ^{
se::ScriptEngine* scriptEngine = se::ScriptEngine::getInstance();
ret = scriptEngine->runScript([path UTF8String]) ;
});
if(!ret) {
ABCLogError(@"call js func fail:%@", path);
}
return ret;
} else {
se::ScriptEngine* scriptEngine = se::ScriptEngine::getInstance();
bool ret = scriptEngine->runScript([path UTF8String]) ;
if(ret == false) {
ABCLogError(@"call jsFunct fail:%@", path);
}
return ret;
}
}
+ (NSString *)JSEvaluateScript:(NSString*)script {
if(script == nil) {
ABCLogError(@"callJSFunc fail, script is null..");
return nil;
}
se::Value *result = new se::Value();
if(![NSThread isMainThread]) {
__block bool ret = NO;
dispatch_sync(dispatch_get_main_queue(), ^{
se::ScriptEngine* scriptEngine = se::ScriptEngine::getInstance();
ret = scriptEngine->evalString([script UTF8String],-1,result);
});
if(!ret) {
ABCLogError(@"call js func fail:%@", script);
}
if(result->isString()){
return [NSString stringWithCString:result->toString().c_str()
encoding:[NSString defaultCStringEncoding]];
}else{
return nil ;
}
} else {
se::ScriptEngine* scriptEngine = se::ScriptEngine::getInstance();
bool ret = scriptEngine->evalString([script UTF8String],-1,result);
if(ret == false) {
ABCLogError(@"call jsFunct fail:%@", script);
}
if(result->isString()){
return [NSString stringWithCString:result->toString().c_str()
encoding:[NSString defaultCStringEncoding]];
}else{
return nil ;
}
}
}
在oc中执行js脚本
NSString *path = [[NSBundle mainBundle] pathForResource:@"driver" ofType:@"js"] ;
if([ABCCallJSService runScript:path]){
NSLog(@"haleli <<< run Script success") ;
NSString *result = [ABCCallJSService JSEvaluateScript:@"mydriver.dumpHierarchy()"] ;
NSLog(@"haleli >>> result : %@" ,result) ;
}else{
NSLog(@"haleli <<< run Script fail") ;
}
七、参考文章:
1、https://cloud.tencent.com/developer/article/1004875
2、https://shadeofgod.github.io/2017-07-08/使用chrome开发者工具调试iOS-webview/
3、http://taobaofed.org/blog/2015/11/27/webkit-remote-debug-action/