南锋

南奔万里空,脱死锋镝余

cocosCreator导出IOS工程热更后依然走旧逻辑的问题

因为这套热梗逻辑是在安卓上已经用的逻辑,而且是没有问题的。于是我也没有多想,直接就拿过来用了,当我看着热更进度到100%之后然后重启app时,我还是蛮开心的,但是很快就发现了不对劲。我发现重启后还是走的旧逻辑。

问题排查

Cocos 3.X常见坑:热更路径要指向assets根目录

我这里指定的路径是 -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大概率是:

1
build/ios/data

热更后本地路径一般类似:

1
Documents/asset

我这里就是没注意,在OC中改路径,导致路径不对。

改了路径后,路径就对了

关键问题

上面路径改了之后问题依然存在,说明没有找到问题的本质原因
关键问题在于

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
38
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);
});

只需要修改上面两个地方就可以啦

+