同一套 Cocos Creator 热更新逻辑在 Android 上工作正常,但移植到 iOS 后,热更新下载到 100% 并重启 App,启动后仍然执行旧代码。文件通常已经下载成功,真正的问题往往是 iOS 启动时没有恢复热更新目录的 searchPaths。
问题排查
检查 Cocos Creator 3.x 热更新目录
我这里指定的路径是 -s ${path.join(result.dest, resdir)}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| exports.onAfterBuild = function (options, result) { let resdir = 'assets';
if (fs.existsSync(path.join(result.dest, 'data'))) { resdir = 'data'; } let cmd = `node version_generator.js -v ${game_version} -u https://lengmo714/${game_version}/ -s ${path.join(result.dest, resdir)} -d ${path.join(Editor.Project.path, "assets\\resources")}`
console.warn("热更地址:", cmd);
exec(cmd, { cwd: Editor.Project.path }, (err, stdout, stderr) => { if (!err) return; console.error(err); }); }
|
iOS大概率是:
热更后本地路径一般类似:
我这里就是没注意,在OC中改路径,导致路径不对。

改了路径后,路径就对了

重点:App 重启后恢复 searchPaths
上面路径改了之后问题依然存在,说明没有找到问题的本质原因
关键问题在于
1 2 3 4 5 6 7 8 9 10 11
| this._am.setEventCallback(null!); this._updateListener = null; var searchPaths = jsb.fileUtils.getSearchPaths(); var newPaths = this._am.getLocalManifest().getSearchPaths(); console.log("---- newPaths", JSON.stringify(newPaths)); Array.prototype.unshift.apply(searchPaths, newPaths); localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths)); jsb.fileUtils.setSearchPaths(searchPaths); setTimeout(() => { game.restart(); }, 100)
|
我这里只在热更完成后setSearchPaths。但是重启后,没有在游戏入口最早的位置重新setSearchPaths。所以iOS依旧走了旧代码。
最简单的方法,在main.js中改成下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| window.self = window; require("src/system.bundle.js");
const jsb = window['jsb']; if (jsb && jsb.fileUtils) { const hotUpdateSearchPaths = localStorage.getItem('HotUpdateSearchPaths'); if (hotUpdateSearchPaths) { const paths = JSON.parse(hotUpdateSearchPaths); jsb.fileUtils.setSearchPaths(paths); console.log("--- restore HotUpdateSearchPaths:", paths); } }
const importMapJson = jsb.fileUtils.getStringFromFile("src/import-map.json"); const importMap = JSON.parse(importMapJson); System.warmup({ importMap, importMapUrl: 'src/import-map.json', defaultHandler: (urlNoSchema) => { require(urlNoSchema.startsWith('/') ? urlNoSchema.substr(1) : urlNoSchema); }, });
System.import('./src/application.js') .then(({ Application }) => { return new Application(); }).then((application) => { return System.import('cc').then((cc) => { require('jsb-adapter/engine-adapter.js'); return application.init(cc); }).then(() => { return application.start(); }); }).catch((err) => { console.error(err.toString() + ', stack: ' + err.stack); });
|
只需要修改上面两个地方就可以啦