你是否曾希望直接将变更推送给特定用户,以便他们立即审查并提供反馈——而无需让他们从 TestFlight 或 Google Play 下载并安装新的 build?
我曾有客户提出改进需求,我能够迅速实现,但要将结果交付给他们验证,要么向所有用户推送更新(对于实验性变更来说风险很大),要么专门为客户创建一个一次性 build(对我们双方来说都很麻烦)。
缺失的是灵活性。开发者希望能够向不同的用户群体(如非技术利益相关者、QA 或整个用户基础,视情况而定)提供不同的更新。
生产环境 build 无法切换到开发中的版本,收集反馈,然后再返回生产环境。
这正是 频道切换 所实现的功能。安装在用户设备上的应用可以在运行时切换更新频道,将生产应用转变为一个用于审查和迭代的灵活空间,而不是一个固定的端点。这对于使用生产应用的非技术利益相关者特别有用,允许他们在已安装的应用中直接测试变更并提供反馈。
了解 Update Channels
更新频道是 Capgo 将更新定向到特定 build 的方式。每个 build 都关联一个频道,该频道决定了它将接收哪些更新。
例如,你可以向某个 preview channel 发布更新,而不会影响 production上的用户。过去,切换 channel 需要安装不同的原生构建版本,或通过 dashboard 手动更改设备分配。
Capgo 中的 channel 可以让你:
- 为具有不同功能的特定用户组设置目标
- 通过将用户分配到不同 channel 来运行 A/B 测试
- 逐步推出新功能
- 创建 Beta 测试计划
- 与个别用户一起调试生产环境问题
如果你不熟悉更新 channel, Capgo channel 文档 对此有更详细的介绍。
什么是 Channel Surfing?
Channel surfing 允许已安装的应用从不同的更新流中拉取内容,而无需重新安装。已安装的应用可以在运行时切换更新通道,并持续接收新选定通道的更新,直到应用被卸载或切换到其他通道。
实际上,这意味着产品负责人或 QA 可以将一个 production build 切换到,例如,一个 preview 通道,以试用最新更改。测试完成后,他们再切换回 production 。无需重新安装或单独的预览 build。
在底层,channel surfing 通过让应用告知更新客户端使用哪个通道来工作。该选择可以在运行时更改,并持续有效,直到被清除或替换。
如何实现 Channel Surfing
在尝试 channel surfing 之前,您的项目需要配置 Capgo Live Updates。要完成设置,请遵循 Capgo 快速入门指南.
Channel surfing 所需的唯一设置是在 Capgo dashboard 中,为您想要切换到的每个通道启用“允许设备自行关联”。 除此之外,无需进行任何 code 更改或配置修改。
其核心在于,频道切换由单次 API 调用驱动:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
await CapacitorUpdater.setChannel({ channel: 'your-channel' });
这会设置查询 Capgo 更新时所使用的频道。 了解 setChannel API 的更多信息.
即时 Channel 切换 (v5.34.0+)
从插件版本 5.34.0、6.34.0、7.34.0 或 8.0.0 开始 (取决于您的主版本), setChannel() 工作方式不同且速度更快:
- 后端校验(只读):向 Capgo 后端发送请求,以校验该 channel 是否被允许
- 本地存储更新:如果校验通过,则将 channel 保存到设备的本地存储中
- 即时生效:下次检查更新时将立即使用新的 channel
此前, setChannel() 会将 channel 覆盖设置保存到后端数据库(例如 Dashboard 或 API 的变更)。设备必须等待后端同步(最多 2 分钟)后才能识别新 channel。新机制只从后端读取(用于校验)并保存到本地,让 channel 切换即时生效。
完整的 channel 切换流程
为了获得更好的用户体验,通常不只是切换 channel 然后等待下次应用重启。常见做法是立即检查更新,有可用更新就下载,然后重新加载应用,让用户直接进入所选 channel 的更新版本。
典型流程如下:
- 切换 channel (
setChannel) - 检查更新(
getLatest) - 获取并应用更新(
download,set或next) - 必要时重新加载应用(
reload)
以下是一个完整示例:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
async function switchChannel(selectedChannel: string) {
try {
// 1. Set the updates channel (with optional auto-update trigger)
await CapacitorUpdater.setChannel({
channel: selectedChannel,
triggerAutoUpdate: true // Immediately check for updates
});
console.log(`Switched to channel: ${selectedChannel}`);
// If you want more control, handle the update manually:
// const latest = await CapacitorUpdater.getLatest();
// if (latest.url) {
// const bundle = await CapacitorUpdater.download({
// url: latest.url,
// version: latest.version
// });
// await CapacitorUpdater.set({ id: bundle.id });
// }
} catch (error) {
console.error('Failed to switch channel:', error);
}
}
// Switch to the beta channel
switchChannel('beta');
如何组织这个流程由你决定。你可以将这些步骤拆分到多次交互中,也可以一次性执行。无论采用哪种结构,都要考虑失败情况。网络问题或无效渠道都可能导致更新无法应用。
唯一要求:启用自我分配
这是启用渠道切换唯一需要做的事情。 在应用使用 setChannel()切换到渠道之前,你必须在 Capgo 仪表板中为该渠道启用自我分配:
- 前往 通道 Capgo dashboard 中的一个板块
- 点击要管理的 channel 名称
- 启用 “允许设备自行关联”
- 保存更改

搞定。无需修改 App 配置,也无需 defaultChannel 进行任何设置。只需在用户可切换到的 channel 上启用 self-assignment 即可。
如果禁用此设置,任何通过该 channel 发起的调用 setChannel() 都将失败,并且 channelPrivate 该事件将会触发。
列出可用 channel
你可以获取可自助分配的 Channel 列表:
const { channels } = await CapacitorUpdater.listChannels();
console.log('Available channels:', channels.map(c => c.name));
// Use this to build a channel selector UI
这只会返回启用了自助分配的 Channel。
获取当前 Channel
查看设备当前分配到哪个 Channel:
const { channel } = await CapacitorUpdater.getChannel();
console.log('Current channel:', channel);
恢复默认 Channel
要移除 Channel 覆盖并恢复默认:
await CapacitorUpdater.unsetChannel({});
这将解除设备与任何指定 Channel 的绑定,使其回退到 defaultChannel 你配置中的 Channel 或云端默认值。
如何测试 Channel 切换
要实际体验 Channel 切换,你需要一个 Release Build —— @capgo/capacitor-updater API 专为 Release Build 设计。在 Debug Build 中,App 通常会从开发服务器加载 JavaScript,从而绕过正常的更新流程。
前提条件
切换频道(channel surfing)的唯一要求是启用 “允许设备自行关联” 在每个允许切换到的频道上。您的应用无需任何配置更改。
创建测试构建
照常构建您的应用:
bun run build && npx cap sync
然后使用 Xcode 或 Android Studio 创建原生构建,或使用你的 CI/CD pipeline。应用将启动于在 Capgo dashboard 中设置为云端默认的 channel。
向不同 Channel 发布更新
应用安装完成后,向不同 channel 发布更新:
# Publish to preview channel
npx @capgo/cli@latest bundle upload --channel preview
# Publish to production channel
npx @capgo/cli@latest bundle upload --channel production
然后,在应用内导航到 channel 切换 UI 并触发切换。应用应从选定的 channel 获取更新并重新加载到新更新。
构建 Channel 切换 UI
Channel 切换通常只希望暴露给有限的用户群体,而不是所有应用用户。例如,你可以为已认证的员工提供一个按钮,将应用切换到 preview channel。
以下是一个用于 channel 切换的 React 组件示例:
import { useState, useEffect } from 'react';
import { CapacitorUpdater } from '@capgo/capacitor-updater';
export function ChannelSwitcher() {
const [currentChannel, setCurrentChannel] = useState<string>('');
const [availableChannels, setAvailableChannels] = useState<string[]>([]);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
loadChannelInfo();
}, []);
async function loadChannelInfo() {
const { channel } = await CapacitorUpdater.getChannel();
setCurrentChannel(channel || 'default');
const { channels } = await CapacitorUpdater.listChannels();
setAvailableChannels(channels.map(c => c.name));
}
async function handleChannelSwitch(channel: string) {
setIsLoading(true);
try {
await CapacitorUpdater.setChannel({
channel,
triggerAutoUpdate: true
});
setCurrentChannel(channel);
// App will update in background or on next restart
} catch (error) {
console.error('Failed to switch channel:', error);
} finally {
setIsLoading(false);
}
}
return (
<div>
<p>Current channel: {currentChannel}</p>
<div>
{availableChannels.map(channel => (
<button
key={channel}
onClick={() => handleChannelSwitch(channel)}
disabled={isLoading || channel === currentChannel}
>
Switch to {channel}
</button>
))}
</div>
</div>
);
}
OTA 更新的坑
这些问题并非 channel 切换独有,但一旦开始在运行时切换 channel,它们往往很快就会显现。
运行时版本不匹配
Capgo 中的更新与原生应用版本绑定。如果某次更新的原生版本与已安装应用的原生版本不匹配,该更新就不会被下载或应用。切换 channel 时,通常表现为应用切换了 channel,但即使该 channel 上有更新,也不会应用该更新。
这通常意味着该更新是基于应用的不同原生版本发布的。请确保你 channel 的 bundle 与设备上安装的原生版本兼容。
移除或撤销更新
如果应用已经为某个 channel 下载了更新,从 Capgo dashboard 中删除该更新并不会将其从已下载的设备上移除。删除操作仅会停止 后续的 下载。
撤销有问题的更新最可靠的方法是向同一个 channel 发布一个已知正常的更新。这会在该 channel 的历史记录顶部创建一个新更新,客户端会将其视为最新版本并应用。
Capgo 还提供了回滚机制,可以指示客户端重新应用之前的稳定更新,或者回退到 build 中内置的更新。
数据迁移注意事项
切换渠道会更改应用运行的 JavaScript bundle。如果应用依赖的迁移或数据格式在不同渠道间不兼容,来回切换可能会导致问题。
例如,如果 beta 更新应用了数据库迁移,生产版本可能无法理解新的 schema。开发者应确保更新在切换时是安全的,或在必要时将切换限制为单向。
为什么渠道切换能提升移动端迭代效率
当您需要快速在生产环境中审查更改时,渠道切换特别有用。
快速验证
想象一下,有一个紧急的 bug 修复,需要在广泛发布前进行验证。借助 channel surfing,可以将该变更隔离给一小部分指定用户,让他们在变更到达生产环境之前先进行审查。
利益相关者审查
产品负责人或 QA 可以将已安装的生产构建切换到另一个更新 channel,验证修复或功能,完成后再切换回来。
简化测试流程
这使得非技术利益相关者更容易参与审查和决策,同时保持工作流顺畅。单个生产构建变成了用于测试、反馈和验证的灵活工具。
使用场景
- QA 测试:让 QA 团队在功能分支之间切换
- Beta 计划:用户选择加入 beta channel 以提前体验
- 利益相关者审查:产品负责人在发布前预览变更
- A/B 测试:将用户分配到不同渠道以进行实验
- 调试:将特定用户切换到调试渠道以诊断问题
对比:渠道切换方法
| 方法 | 生效时间 | 持久化位置 | 使用场景 |
|---|---|---|---|
setChannel() 来自插件 |
即时 | 仅限设备(本地) | 用户在 App 内主动切换 Channel |
| Dashboard 设备覆盖 | 最多 2 分钟 | 后端数据库 | 管理员针对特定设备发起的变更 |
| API Channel 分配 | 最多 2 分钟 | 后端数据库 | 自动化后端集成 |
构建频道切换 UI 时,为了获得最佳用户体验,请始终使用插件的 setChannel() 方法。
最佳实践
- 限制访问权限: 渠道切换通常仅供内部使用——不要向所有用户开放
- 处理错误: 切换渠道时,务必妥善处理错误
- 验证兼容性: 确保不同渠道的更新与已安装的 native 版本兼容
- 编写渠道文档:为每个渠道保留清晰的用途文档
- 监控使用情况:跟踪各设备所属渠道以便调试
资源
总结
频道切换彻底改变了你迭代 Capacitor 应用的方式。生产构建不再是固定的终点,而是用于测试、验证和快速迭代的灵活工具。
借助近期插件版本引入的即时频道切换功能,体验如今已无缝衔接——用户切换频道后,无需等待即可立即接收新频道的更新。
无论是与利益相关者验证 bug 修复、运行 Beta 计划,还是调试特定用户的问题,频道切换都能让你灵活地在正确的时间将正确的更新推送给正确的用户。
继续阅读《Capgo 频道切换:如何在运行时切换更新频道》
如果你正在使用 玩转 Capgo 频道:如何在运行时切换更新频道 要规划 Channel 路由和分阶段发布,请将其与 通道 有关 Channels 的实现细节, 通道 有关 Channels 的实现细节, 通道 有关 Channels 的实现细节, Beta 测试解决方案 适用于 Beta Testing Solution 产品工作流的,以及 版本定向解决方案 适用于 Version Targeting Solution 产品工作流的。