研究基于 Flutter Shorebird 热更新支持中国区域的问题

研究基于 Flutter Shorebird 热更新支持中国区域的问题

在写这一篇文章之前,我并不知道结果,我现在想把过程写出来。

问题如下

Shorebird 支持对于 iOS 和 android 平台的代码无感知的热更新,目前 iOS 还处于 Alpha 阶段,存在执行速度比 Android 慢 100 倍,但是对于一些方法执行只需要几毫秒,我觉得影响不大,只要能在线上紧急的处理一些重要的 BUG。

对于怎么集成 Shorebird 我就不过多的说明,大家可以自行前往 shorebird.dev 看说明文档。

目前我们的项目已经升级到 Flutter 3.13.2 版本,已经符合 Shorebird 支持的条件,我觉得重新拉取分支进行接入。

但是不幸的是对于中国区域不支持,比如执行 Shorebird 对于 FLUTTER_STORAGE_URL 不支持,这个问题不大我们可以开启代理,unset 这个参数即可。

目前主要的问题是,Shorebird 将补丁存在在谷歌存储,对于国内的用户无法下载,导致最后一步热更新的流程阻塞。

分析问题

对于之前的 Shorebird 版本可以在日志看到返回补丁的资源路径,可以在代理下载出来。我再想能否可以在开发完毕补丁之后,将补丁上传到 Shorebird 之后。再下载下来,之后上传到自己的服务器,将自己服务器的补丁下载在 App 目录下面,这样 Shorebird 就可以知道正常的加载补丁热更了。

但是不幸运的是,最新版本的 Shorebird 已经屏蔽了请求补丁日志的输出,我们无法获取到最新补丁的资源的路径,就在我准备放弃这个方案的时候,我在 Github 搜索到一个大神的一篇文章。

github.com/popeyelau/w...

我们可以通过下面的请求获取到补丁的地址

json 复制代码
curl -X "POST" "https://api.shorebird.dev/api/v1/patches/check" \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "platform": "ios", # 平台
  "arch": "aarch64", # 架构
  "release_version": "1.0.0+1697186586", # App 对应版本
  "app_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # App Id
  "channel": "stable",
  "patch_number": 0 # 当前补丁号
}'

最后我们获取到下面的请求返回

json 复制代码
{
    "patch_available": true,
    "patch": {
        "number": 1,
        "download_url": "https://storage.googleapis.com/shorebird_patch_artifacts/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/ios/aarch64/xxxxxx/dlc.vmcode",
        "hash": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
}

我们成功拿到了最新的补丁号和补丁的下载地址。

iOS 存放补丁相关文件在下面的路径 AppData/Library/Application\ Support/shorebird

没有加载任何补丁的的文件如下

json 复制代码
// state.json
{
  "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "release_version": "1.0.0+1697186586", # 版本号
  "queued_events": []
}

手机开启代理,也不能直接下载谷歌的资源,目前不知道原因。但是竟然有一次成功了,成功加载补丁的文件如下。

其中 downloads/1 和 patches/1/dlc.vmcode 是同一个补丁文件。

json 复制代码
// patches_state.json
{
  "last_booted_patch": {
    "number": 1, // 上一次补丁的版本号
    "size": 18434176 // 上一次补丁的大小
  },
  "next_boot_patch": {
    "number": 1, // 下一次补丁的版本号
    "size": 18434176 // 下一次补丁的大小
  },
  "highest_seen_patch_number": 1
}

这中间下载完毕的的文件我没有看到具体样子,中间的逻辑不是很清楚。但是我通过将上面的文件复制到导出的.xcappdata 里面,之后重新替换之后,我发现确实已经更新了最新了补丁。

为了验证我的猜想我,准备再打一个补丁 2,按照上面结构进行修改看看是否可以。

我修改上面的文件结构如下

之后修改 patches_state.json 的内容如下

json 复制代码
{
  "last_booted_patch": {
    "number": 1,
    "size": 18434176
  },
  "next_boot_patch": {
    "number": 2,
    "size": 18454248
  },
  "highest_seen_patch_number": 2
}

最新文件的大小可以通过下面的方式获取(macOS)

这简介里面可以看到,之后我们将修改的Container 重新导入覆盖,重新打开 App 果然已经走最新的补丁了。

从此处的实验,我们可以可以得到了一个结论,我们可以通过这样的结论做到使用 Shorebird 在国内内容热更新服务。

上面只是我们人工走完了流程,但是整个还需要和后台配合,将资源下载放在后台,之后通过编写 Flutter 库操作 iOS 的文件做到这样的效果。

关于如何在国内使用 Shorebird 热更新服务的整套逻辑已经讲完了,剩下的就完善这中间的过程,写代码实现自动化的过程。

相关推荐
BG1 天前
Flutter 简仿Excel表格组件介绍
flutter
zhangmeng1 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
恋猫de小郭1 天前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
卡尔特斯1 天前
Flutter A GlobalKey was used multipletimes inside one widget'schild list.The ...
flutter
w_y_fan2 天前
Flutter 滚动组件总结
前端·flutter
醉过才知酒浓2 天前
Flutter Getx 的页面传参
flutter
火柴就是我3 天前
flutter 之真手势冲突处理
android·flutter
Speed1233 天前
`mockito` 的核心“打桩”规则
flutter·dart
法的空间3 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
恋猫de小郭3 天前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter