最近需要开发一个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内核。
软件测试之Cocos Creator Monkey(ios)——获取JS页面

1、JavaScript引擎

JavaScript引擎是专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。第一个JavaScript引擎由布兰登·艾克在网景公司开发,用于Netscape Navigator网页浏览器中。JavaScriptCore就是一个JavaScript引擎。
软件测试之Cocos Creator Monkey(ios)——获取JS页面

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 中进行调试:
    软件测试之Cocos Creator Monkey(ios)——获取JS页面

三、使用JSB进入Cocos Creator的js世界

1、远程调试原理浅析(ios)

Cocos Creator支持远程调试IOS,是因为Cocos Creator里面支持JavaScriptCore引擎,客户端通过Safari调试协议即可远程调试app内的JavaScript。在程序内部要获取JavaScript页面,可以通过CocosCreator提供的JSB进行获取,在ios侧,JSB底层就是封装了一个JavaScriptCore。
软件测试之Cocos Creator Monkey(ios)——获取JS页面

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/

相关文章:

  • 2021-06-19
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
  • 2021-10-01
  • 2022-12-23
  • 2021-11-20
  • 2021-11-21
猜你喜欢
  • 2021-05-05
  • 2022-02-15
  • 2022-12-23
  • 2022-12-23
  • 2021-12-05
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案