ios上js引擎的使用,javascriptcore和v8

时间:2024-10-02 11:36:54

          如上篇文章所述ios折线图绘制,公司开发需要要用到一些字符串转公式的需求。自己实在有点惧自己写语法书啥的听公司大牛说可以使用js引擎试试,于是就抱着试试的态度调研了一把,感觉还不错。

        这次试用了两个js引擎,一个是javascriptcore,这个比较方便可以直接引入便使用,另一个是google的v8引擎,这个有点麻烦要先编译通过才行,搞了好一阵才派上用场~倒是学到了好多新知识,哈哈。

先说简单的javascriptcore吧,下载好库引入静态链接库和头文件便可以了。这里有时候会报错说找不到文件。google了一下发下一般是因为xcode本身对外来拷贝文件没有正确引用导致的,解决办法很简单,进入Build Phases 的Compile Source对新添加的头文件进行引用就好了。

        

        接下来便是怎样使用的问题。

        先在头文件里引用文件:

import "JavaScriptCore/"

        然后是构造js的上下文context,这个还蛮重要的东西,具体的原理大家可以自行google,因为我自己理解的也很肤浅,略知皮毛而已。

context = JSGlobalContextCreate(NULL);

        完了以后我把js运行的方法封装成了一个方法,如下:

  1. //js代码运行
  2. - (NSString *)runsJS:(NSString *)aJSString
  3. {
  4. if (!aJSString) {
  5. NSLog(@"[JSC] JS String is empty!");
  6. return nil;
  7. }
  8. JSStringRef scriptJS = JSStringCreateWithUTF8CString([aJSString UTF8String]);
  9. JSValueRef exception = NULL;
  10. JSValueRef result = JSEvaluateScript(context, scriptJS, NULL, NULL, 0, &exception);
  11. NSString *res = nil;
  12. JSStringRef jstrArg = JSValueToStringCopy(context, result, NULL);
  13. res = (NSString*)JSStringCopyCFString(kCFAllocatorDefault, jstrArg);
  14. JSStringRelease(jstrArg);
  15. JSStringRelease(scriptJS);
  16. return res;
  17. }

       封装完毕便可以顺利使用啦:

  1. NSString *str=[ runJS:@"var str='';for(var i=0;i<2;i++){str= str + '\\n' + i + ' :Hello' + ', World!';}"];
  2. //NSLog(@"%@",str);

      这便是大体的javascriptcore的使用方法了。


      接下来是v8引擎。

      v8引擎的编译很痛苦,网上一般比较常见的教程是编译成动态库,lib之类的,但苹果貌似只让用.a的静态库,无形中又增加了负担。我网上搜了好多编译的方法,无非都是些svn check下v8的文件,然后安装python和对应python的一个编译工具scons进行编译。看攻略说,google先在又不提倡用scons了,又开发了另外一种东西....真是能折腾。

      我遇到的主要问题是好像编译的时候要搭配一个叫breakpad的东西一起,而这玩意儿又死活装不了,就一直卡在那里了。但比较意外的是最后经竟意外发现在v8根目录还有个make的命令,也可以直接编译.....就这样稀里糊涂的把静态库给整出来了,还隐藏得很深,search了一下才发现在哪里。

      

          这便是粗略的使用方法啦。

          这边还有个问题是我在js引擎里使用数组然后返回到ios工程的时候,比如这样:

  1. var test=function(){
  2. var val=[];
  3. val["1.0"]=1;
  4. val["1.1"]=2;
  5. val["1.2"]=3;
  6. val["1.3"]=4;
  7. val["2"]=34;
  8. var str="var v=; v[\"1.3\"]=v[\"1.0\"]*v[\"1.2\"];";
  9. var fun=new Function(str);
  10. val["0"]=5;
  11. fun();
  12. return val;
  13. }

        当我返回的时候只能返回整数位的下标,小数位的全被舍弃了,试验了javascriptcore和v8都一样的结果,想是不是js引擎本身的实现机理问题,路过的大神有懂的麻烦帮忙解决一下~