在最近发布的 NativeScript 6.0 版本中,我们宣布了一项名为NativeScript AppSync的新 Beta 服务,该服务允许您更新使用 NativeScript 构建的 iOS 和 Android 应用,无需使用 App Store 或 Google Play。
如果您还没有看到此功能的实际应用,则可以观看最近NativeScript 6.0 发布网络研讨会中的这段 7 分钟的片段来快速了解。
在本文中,我想超越基本的演示,并回答一些关于使用此服务的一些常见问题。例如,您首先为什么要这样做,以及 Apple 是否允许我在我的应用中启用此功能?
每个更新过 Android 或 iOS 应用的人都讨厌这个过程。每次更新都涉及许多手动步骤,例如创建新的发布版本、更改版本号等一系列配置、编写发行说明,以及在 iOS 上等待审核才能发布更新。
而且问题不仅仅限于开发人员的生产力。假设您在生产应用中发现了一个错误,该错误正在给您的业务造成经济损失。要使用正常的部署流程修复该错误,您必须:手动创建应用的发布版本,将该版本上传到商店,等待批准(在 iOS 上),然后等待用户在他们的设备上下载并安装该更新。
此过程很容易花费几天时间,在此期间,您的业务正在损失金钱,并且您的用户会因您的应用存在错误而感到沮丧。使用 NativeScript AppSync,您可以大大加快更新过程。
AppSync 服务有几个不同的组件,我认为单独解释它们是展示服务整体工作原理的最佳方式。
AppSync CLI
AppSync 服务有其自己的命令行界面,您可以使用npm install -g nativescript-app-sync-cli
进行安装。安装后,您将在终端上获得一个新的nativescript-app-sync
命令,您可以使用它与 AppSync 服务器进行交互。
CLI 允许您注册 AppSync 服务,添加您希望使用该服务的应用,上传这些应用的代码更新等等。
AppSync 服务器
NativeScript AppSync 服务器提供了一个前端,用于查看连接您的应用程序代码与 AppSync 服务器所需的访问密钥和部署密钥。
当您通过 AppSync CLI 上传更新时,服务器还会保存您的应用更新(即您的实际应用文件)。
AppSync 插件
拼图的最后一块是AppSync 插件,您可以使用tns plugin add
将其安装到任何 NativeScript 应用中。
tns plugin add nativescript-app-sync
安装插件后,您需要使用以下代码在应用中添加对 AppSync 插件的sync()
方法的调用。
import { AppSync } from "nativescript-app-sync";
AppSync.sync({
deploymentKey: "..."
});
AppSync.sync()
方法调用 AppSync 服务器以检查您的应用是否有任何新的更新可用。如果找到更新,则插件方法会静默地在后台下载该更新,并在用户下次重新启动应用时应用该更新。
从技术上讲,您可以在应用中的任何位置调用AppSync.sync()
,并且可以根据需要调用任意次数。但是,最常见的方法是将以下代码片段放在您的app.js
文件中(对于 NativeScript Core 和 NativeScript-Vue),或放在您的main.ts
文件中(对于 NativeScript Angular)。
import * as application from "tns-core-modules/application";
import { AppSync } from "nativescript-app-sync";
application.on(application.resumeEvent, () => {
AppSync.sync(...);
});
此代码将事件处理程序附加到您的 NativeScript 应用的resume
事件,NativeScript 在每次用户恢复您的应用时都会触发该事件。
注意:当用户启动您的应用或从设备上的其他应用切换到您的应用时,会发生
resume
事件。
需要注意的是,AppSync.sync()
仅确定更新是否可用,如果可用,则在后台下载该更新。sync()
方法实际上不会应用更新——毕竟,需要更改的是应用的源代码本身,而这在应用运行时是无法做到的。
话虽如此,您可以使用一些选项来确认您的应用程序同步工作方式。
AppSync 插件的sync()
方法允许您以多种不同的方式配置应用程序同步的工作方式。以下是可用的一些选项及其默认值的快速浏览。
import { AppSync, InstallMode, SyncStatus } from "nativescript-app-sync";
import { isIOS } from "tns-core-modules/platform";
AppSync.sync({
deploymentKey: isIOS ? "your-ios-deployment-key" : "your-android-deployment-key",
installMode: InstallMode.ON_NEXT_RESTART,
mandatoryInstallMode: isIOS ? InstallMode.ON_NEXT_RESUME : InstallMode.IMMEDIATE,
updateDialog: {
updateTitle: "Please restart the app",
optionalUpdateMessage: "Optional update msg",
mandatoryUpdateMessage: "Mandatory update msg",
optionalIgnoreButtonLabel: "Later",
mandatoryContinueButtonLabel: isIOS ? "Exit now" : "Restart now",
appendReleaseDescription: true
}
});
以下是一些关于每个选项如何工作的更多信息。
deploymentKey
:deploymentKey
是必需的,因为它将您的应用程序代码连接到 AppSync 服务器。iOS 和 Android 将具有不同的密钥,因此示例代码包含一个三元检查,允许您粘贴两个值。
installMode
:默认情况下,AppSync 仅在用户重新启动应用时安装更新。但是,AppSync 确实具有立即应用更新的功能,如果您将installMode
设置为InstallMode.IMMEDIATE
,则会立即应用更新。但这有一个很大的警告:InstallMode.IMMEDIATE
会显示安装提示(请参见下面的图片),而 Apple 不允许通过 App Store 分发的 iOS 应用这样做。因此,仅当您构建企业分发的 iOS 应用时,才在 iOS 上设置InstallMode.IMMEDIATE
。
mandatoryInstallMode
:当您通过 AppSync CLI(nativescript-app-sync release
)发布 AppSync 更新时,您可以选择使用--mandatory
标志将该版本指定为强制版本。mandatoryInstallMode
选项使您能够立即安装标记为强制的更新,同时允许非强制更新等到下次应用重新启动时再安装。再次强调,不要对通过 App Store 分发的 iOS 应用使用立即发布。
updateDialog
:AppSync 插件有一个内置机制,用于在使用InstallMode.IMMEDIATE
时显示一个对话框,通知用户有关更新的信息。下面的 GIF 演示了 Android 和 iOS 上的对话框。在 Android 上,插件能够立即使用新的更改重新启动您的应用。在 iOS 上,应用不允许自行重新启动,因此插件对话框改为指示用户手动重新启动应用。(大概是因为用户体验不佳,所以 Apple 不希望您对通过 App Store 分发的应用使用这种工作流程。)
AppSync 插件的sync()
方法还接受一个回调函数作为第二个参数,该函数报告sync()
方法的进度。以下是其在实际应用中的样子。
import * as application from "tns-core-modules/application";
import { AppSync, SyncStatus } from "nativescript-app-sync";
application.on(application.resumeEvent, () => {
AppSync.sync({
...
}, (syncStatus: syncStatus) => {
if (syncStatus === SyncStatus.UP_TO_DATE) {
console.log("No pending updates; you’re running the latest version.");
} else if (syncStatus === SyncStatus.UPDATE_INSTALLED) {
console.log("Update found and installed. It will be activated upon next cold reboot");
}
});
});
您可能会发现此回调在调试或排查生产应用问题时很有用。
让我们从这个问题的简单部分开始。如果您使用企业开发证书开发 iOS 应用,则可以根据自己的意愿推送更新,并根据自己的意愿通知用户这些更新;Apple 实际上只关心通过 App Store 分发的应用。
对于 App Store,Apple 制定了此准则。
应用可以包含或运行未嵌入二进制文件中的代码(例如基于 HTML5 的游戏、机器人等),只要代码分发不是应用的主要目的,代码不在商店或类似商店的界面中提供,并且只要软件 (1) 是免费的或使用应用内购买购买的;…
完整文本中有很多法律术语,但关键部分是这个。
应用可以包含或运行未嵌入二进制文件中的代码,只要代码分发不是应用的主要目的。
基本上,只要您的应用不是将代码分发作为应用本身的功能,并且只要您不滥用 AppSync 从根本上更改应用的目的(例如突然将您的日历应用变成赌博应用),您就可以放心使用。
值得注意的是,NativeScript AppSync 基于 Microsoft 的 CodePush 项目,该项目已被数千名开发人员用于部署和更新 iOS 应用程序。
注意:Apple 已明确表示他们不希望您的应用向用户显示更新对话框,因此,再次强调,请确保您不要在通过 App Store 分发的 iOS 应用上使用
InstallMode.IMMEDIATE
。
您可能希望将许多其他 AppSync 功能整合到您的开发工作流程中。
例如,AppSync CLI 和服务器能够分别处理暂存和生产版本,使您能够在将更新发送给生产用户之前在本地测试更新。
此外,AppSync CLI 和服务器都提供了部署历史记录数据,包括您推送出的更新的确切用户数量。如果出现问题,您甚至可以使用nativescript-app-sync rollback
回滚更新。
$ nativescript-app-sync deployment history ACMEAndroid Staging
┌───────┬──────────────┬─────────────┬───────────┬─────────────┬───────────────────────┐
│ Label │ Release Time │ App Version │ Mandatory │ Description │ Install Metrics │
├───────┼──────────────┼─────────────┼───────────┼─────────────┼───────────────────────┤
│ v1 │ 2 hours ago │ 1.0 │ No │ │ Active: 100% (1 of 1) │
│ │ │ │ │ │ Total: 1 │
└───────┴──────────────┴─────────────┴───────────┴─────────────┴───────────────────────┘
如您所见,AppSync 可以提供很多功能来改进您的开发工作流程,并帮助您更快地将修复程序交付给用户。有关更多详细信息,请参阅NativeScript 市场上的 AppSync 插件文档,如果您对使用插件有任何其他疑问,请随时在评论中提出。