在AeroFS,我们即将发布我们的第一个 React Native 应用。一旦推出,我们希望通过空中发送更新来绕过缓慢的 AppStore 审核过程,并加快发布周期。我们创建了 ReactNativeAutoUpdater
来实现这一目的。它是我们2015 感恩节黑客马拉松的一部分。
苹果允许这样做吗?
是的!iOS 开发者计划第 3.3.2 节允许这样做,“只要这样的脚本和代码不会通过提供与应用程序预期和宣传目的不一致的功能或功能来改变应用程序的主要目的。”
React Native 的 jsbundle
可以轻松超过几兆字节。在蜂窝连接中,下载比所需的更多,这并不是一个好主意。为了解决这个问题,我们需要决定是否需要下载此捆绑包。
我们通过与初始版本的 jsbundle
一起发货应用来解决这个问题,这减少了初始启动时的延迟。然后我们开始查询可用更新,并下载更新的 jsbundle
。应用的所有后续运行都使用此更新的捆绑包。
为了决定是否下载 jsbundle
,我们需要了解一些关于捆绑包的 元 信息。对于 ReactNativeAutoUpdater
,我们将这些 元 信息作为 JSON 文件的形式存储在互联网上的某个地方。JSON 的格式如下
{
"version": "1.1.0",
"minContainerVersion": "1.0",
"url": {
"url": "/s/3klfuwm74sfnj0w/main.jsbundle?raw=1",
"isRelative": true
}
}
以下 JSON 字段的意义
version
— 这是捆绑文件版本(以 major.minor.patch 格式表示)minContainerVersion
— 这是允许下载此捆绑包的容器(本地)应用程序的最低版本(这是必需的,因为向您的应用程序添加新的 React Native 组件可能会导致本地应用程序更改,因此需要通过 AppStore 审核流程)url.url
— 这是 ReactNativeAutoUpdater
将从中下载 JS 捆绑的地方url.isRelative
— 这告诉提供的 URL 是否为相对 URL(当设置为 true
时,您需要使用方法 (void)setHostnameForRelativeDownloadURLs:(NSString*)hostname;
设置主机名)ReactNativeAutoUpdater
需要知道初始化时此 JSON 文件的位置。
以下是 ReactNativeAutoUpdater
的 GIF 录制屏幕视频。
ReactNativeAutoUpdater 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod "ReactNativeAutoUpdater"
要运行示例项目,首先在 Example
目录中运行 npm install
,然后在 iOS
目录中运行 pod install
。
在您的 AppDelegate.m
#import <ReactNativeAutoUpdater/ReactNativeAutoUpdater.h>
以下代码基本上遵循以下步骤。
ReactNativeAutoUpdater
的一个实例self
设置为 delegate
metadataUrl
和 defaultJSCodeLocation
初始化checkUpdate
、checkUpdateDaily
或 checkUpdateWeekly
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// defaultJSCodeLocation is needed at least for the first startup
NSURL* defaultJSCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
ReactNativeAutoUpdater* updater = [ReactNativeAutoUpdater sharedInstance];
[updater setDelegate:self];
// We set the location of the metadata file that has information about the JS Code that is shipped with the app.
// This metadata is used to compare the shipped code against the updates.
NSURL* defaultMetadataFileLocation = [[NSBundle mainBundle] URLForResource:@"metadata" withExtension:@"json"];
[updater initializeWithUpdateMetadataUrl:[NSURL URLWithString:JS_CODE_METADATA_URL]
defaultJSCodeLocation:defaultJSCodeLocation
defaultMetadataFileLocation:defaultMetadataFileLocation ];
[updater setHostnameForRelativeDownloadURLs:@"https://www.aerofs.com"];
[updater checkUpdate];
NSURL* latestJSCodeLocation = [updater latestJSCodeLocation];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
self.window.rootViewController = rootViewController;
RCTBridge* bridge = [[RCTBridge alloc] initWithBundleURL:url moduleProvider:nil launchOptions:nil];
RCTRootView* rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"ReactNativeAutoUpdater" initialProperties:nil];
self.window.rootViewController.view = rootView;
[self.window makeKeyAndVisible];
return YES;
}
如果您愿意,可以在更新下载后立即要求用户应用更新。为此,请实现代理方法。查看示例应用程序以查看一个工作示例。
ReactNativeAutoUpdater
可高度配置。以下是您可以配置的选项
ReactNativeAutoUpdater *updater = [ReactNativeAutoUpdater sharedInstance];
/* Show progress during the udpate
* default value - YES
*/
[updater showProgress: NO];
/* Allow use of cellular data to download the update
* default value - NO
*/
[updater allowCellularDataUse: YES];
/* Decide what type of updates to download
* Available options -
* ReactNativeAutoUpdaterMajorUpdate - will download only if major version number changes
* ReactNativeAutoUpdaterMinorUpdate - will download if major or minor version number changes
* ReactNativeAutoUpdaterPatchUpdate - will download for any version change
* default value - ReactNativeAutoUpdaterMinorUpdate
*/
[updater downloadUpdatesForType: ReactNativeAutoUpdaterMajorUpdate];
/* Check update right now
*/
[updater checkUpdate];
/* Check update daily - Only check update once per day
*/
[updater checkUpdateDaily];
/* Check update weekly - Only check updates once per week
*/
[updater checkUpdatesWeekly];
/* When the JSON file has a relative URL for downloading the JS Bundle,
* set the hostname for relative downloads
*/
[updater setHostnameForRelativeDownloadURLs:@"https://www.aerofs.com/"];
不要忘记为与应用程序一起提供的 JS 代码提供 ReactNativeAutoUpdater 的元数据文件。该文件中的元数据用于将发货的 JS 代码与更新进行比较。感谢 @arbesfeld 指出这一错误。
ReactNativeAutoUpdater 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。