Mac平台iOS CocosCreator热更新功能
-
使用 Version Generator 来生成 Manifest 文件
在范例工程中,我们提供了一个 version_generator.js(GitHub | 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地址:
网友评论