美文网首页
Mac平台iOS CocosCreator热更新功能

Mac平台iOS CocosCreator热更新功能

作者: sws1314 | 来源:发表于2021-04-30 21:07 被阅读0次

    Mac平台iOS CocosCreator热更新功能

    1. 下载官方热更新demo 2.3.3版本

    2. 使用 Version Generator 来生成 Manifest 文件

      在范例工程中,我们提供了一个 version_generator.jsGitHub | Gitee

      var fs = require('fs');
      var path = require('path');
      var crypto = require('crypto');
      
      var manifest = {
          packageUrl: 'http://localhost/tutorial-hot-update/remote-assets/',
          remoteManifestUrl: 'http://localhost/tutorial-hot-update/remote-assets/project.manifest',
          remoteVersionUrl: 'http://localhost/tutorial-hot-update/remote-assets/version.manifest',
          version: '1.0.0',
          assets: {},
          searchPaths: []
      };
      
      var dest = './remote-assets/';
      var src = './jsb/';
      
      // Parse arguments
      var i = 2;
      while ( i < process.argv.length) {
          var arg = process.argv[i];
      
          switch (arg) {
          case '--url' :
          case '-u' :
              var url = process.argv[i+1];
              manifest.packageUrl = url;
              manifest.remoteManifestUrl = url + 'project.manifest';
              manifest.remoteVersionUrl = url + 'version.manifest';
              i += 2;
              break;
          case '--version' :
          case '-v' :
              manifest.version = process.argv[i+1];
              i += 2;
              break;
          case '--src' :
          case '-s' :
              src = process.argv[i+1];
              i += 2;
              break;
          case '--dest' :
          case '-d' :
              dest = process.argv[i+1];
              i += 2;
              break;
          default :
              i++;
              break;
          }
      }
      
      
      function readDir (dir, obj) {
          var stat = fs.statSync(dir);
          if (!stat.isDirectory()) {
              return;
          }
          var subpaths = fs.readdirSync(dir), subpath, size, md5, compressed, relative;
          for (var i = 0; i < subpaths.length; ++i) {
              if (subpaths[i][0] === '.') {
                  continue;
              }
              subpath = path.join(dir, subpaths[i]);
              stat = fs.statSync(subpath);
              if (stat.isDirectory()) {
                  readDir(subpath, obj);
              }
              else if (stat.isFile()) {
                  // Size in Bytes
                  size = stat['size'];
                  md5 = crypto.createHash('md5').update(fs.readFileSync(subpath)).digest('hex');
                  compressed = path.extname(subpath).toLowerCase() === '.zip';
      
                  relative = path.relative(src, subpath);
                  relative = relative.replace(/\\/g, '/');
                  relative = encodeURI(relative);
                  obj[relative] = {
                      'size' : size,
                      'md5' : md5
                  };
                  if (compressed) {
                      obj[relative].compressed = true;
                  }
              }
          }
      }
      
      var mkdirSync = function (path) {
          try {
              fs.mkdirSync(path);
          } catch(e) {
              if ( e.code != 'EEXIST' ) throw e;
          }
      }
      
      // Iterate res and src folder
      readDir(path.join(src, 'src'), manifest.assets);
      // readDir(path.join(src, 'assets'), manifest.assets);
      readDir(path.join(src, 'res'), manifest.assets);
      
      var destManifest = path.join(dest, 'project.manifest');
      var destVersion = path.join(dest, 'version.manifest');
      
      mkdirSync(dest);
      
      fs.writeFile(destManifest, JSON.stringify(manifest), (err) => {
        if (err) throw err;
        console.log('Manifest successfully generated');
      });
      
      delete manifest.assets;
      delete manifest.searchPaths;
      fs.writeFile(destVersion, JSON.stringify(manifest), (err) => {
        if (err) throw err;
        console.log('Version successfully generated');
      });
      

    具体的使用方法我们封装在一个shell脚本中,因为涉及到资源文件和manifest的拷贝:

    genter_update_resource.sh 文件内容:

    #!/bin/bash
    
    if [[ $# -eq 0 || $0 -eq 0 ]]; then
        #statements
        echo "请输入版本号! 例如: ./genter_update_resource.sh 1.0.0"
        exit
    fi
    
    # 生成文件, (注意: 输出目录直接写成"assets/resources/", 目前测试结果是只有写这个地址才能成功)
    node ./version_generator.js -v $1 -u http://10.23.64.229:8000/tutorial-hot-update/remote-assets/ -s build/jsb-link -d assets/resources/
    
     # 拷贝res和src到工程文件夹,使用anywhere来开启文件夹映射
     cp -R ./build/jsb-link/res ./remote-assets
     cp -R ./build/jsb-link/src ./remote-assets
     echo "拷贝res和src---完成!"
    
     # 拷贝res和src
     cp -R ./assets/resources/project.manifest ./remote-assets
     cp -R ./assets/resources/version.manifest ./remote-assets
     echo "拷贝project.manifest和version.manifest---完成!"
    
    
    # 拷贝res和src到本地服务器上
    #cp -R ./build/jsb-link/res /usr/local/var/www/sws
    #cp -R ./build/jsb-link/src /usr/local/var/www/sws
    #echo "拷贝res和src---完成!"
    #
    ## 拷贝res和src
    #cp -R ./assets/project.manifest /usr/local/var/www/sws
    #cp -R ./assets/version.manifest /usr/local/var/www/sws
    #echo "拷贝project.manifest和version.manifest---完成!"
    
    上面这个最需要注意的是 输出文件目录只能是`assets/resources/`才能成功更新!
    

    使用方法

    ./genter_update_resource.sh 1.0.1
    

    在本地开启anywhere, 需要在项目的根目录的上一层目录执行:

    # 安装anywhere 
    sudo npm install anywhere -g
    
    # 开启静态资源服务器
    anywhere
    

    4.在iOS这边,遇到一个奇葩问题,就是cocos-2d在沙盒中创建文件夹一直失败, 提示是没有权限, 初步判断是因为NSFileManager没有正确获取的原因.

    bool FileUtilsApple::createDirectory(const std::string& path)
    {
        CCASSERT(!path.empty(), "Invalid path");
        
        if (isDirectoryExist(path))
            return true;
        
        NSError* error;
        NSString *filePath = [NSString stringWithUTF8String:path.c_str()];
    //    NSLog(@"创建文件夹: %@", createPath);
        if (filePath.length==0) {
            return NO;
        }
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isSuccess = YES;
        BOOL isExist = [fileManager fileExistsAtPath:filePath];
        if (isExist==NO) {
            NSError *error;
            if (![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error]) {
                isSuccess = NO;
                NSLog(@"creat Directory Failed:%@",[error localizedDescription]);
            }
        }
        
        /// 这是官方代码,这里一直报没有权限的问题.
    //    bool result = [s_fileManager createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:&error];
        if(!isSuccess && error != nil)
        {
            CCLOGERROR("Fail to create directory \"%s\": %s", path.c_str(), [error.localizedDescription UTF8String]);
        }
        return isSuccess;
    }
    

    附上本文的Demo地址:

    gitee

    相关文章

      网友评论

          本文标题:Mac平台iOS CocosCreator热更新功能

          本文链接:https://www.haomeiwen.com/subject/svdorltx.html