Docs 菜单
Docs 主页
/ /
管理 Realm 文件

打包 Realm - Flutter SDK

您可能希望在移动应用程序中播种一些初始数据,这些数据将在应用程序首次启动时提供给用户。 为此,您可以在 Flutter 应用程序中捆绑现有的 Realm 文件。

如果您的应用使用 同步域,您可能不希望对其进行捆绑。 有关更多信息,请参阅捆绑同步Realm部分。

提示

考虑初始数据回调

1

使用与生产应用程序相同的Realm 对象模式创建一个新项目。 打开包含要捆绑的数据的现有 域 ,或创建新 域。

使用Realm.config.path 属性获取域文件的路径。

print("Bundling realm");
final config = Configuration.local([Car.schema], path: 'bundle.realm');
final realm = Realm(config);
realm.write(() {
realm.add(Car(ObjectId(), "Audi", model: 'A8'));
realm.add(Car(ObjectId(), "Mercedes", model: 'G Wagon'));
});
print("Bundled realm location: " + realm.config.path);
realm.close();

提示

使用 Dart 独立运行的实例 SDK 创建捆绑 Realm

出于以下原因,您可能希望使用Dart Standalone SDK为 Flutter 应用程序创建捆绑 Realm:

  • 创建捆绑 Realm 不需要任何 Flutter 用户界面元素。

  • Dart 独立运行的实例所需的样板代码少于 Flutter 项目

2

现在您已经拥有了包含“种子”数据的域副本,您需要将其与生产应用程序捆绑在一起。

将域文件添加到应用程序的 Flutter 资产中。示例,您可以在项目中的位置assets/bundled.realm 添加捆绑域 。

将对捆绑 域 的引用添加到pubspec.yaml文件中,以将其包含在生产应用程序中:

pubspec.yaml
flutter:
assets:
- realm/bundle.realm
3

现在您已拥有应用中包含的 Realm 副本,您需要添加代码来使用它。

在部署带有捆绑 Realm 的应用程序之前,您需要从嵌入式资源中提取 Realm,将其保存到应用程序的数据位置,然后在应用程序中打开这个新 Realm。 以下代码展示了如何在应用程序启动期间执行此操作。

创建辅助函数initBundledRealm 来检查应用中是否已存在捆绑域 ,如果不存在则将其加载到应用中。在调用使用initBundledRealm runApp() 加载应用程序的窗口小部件之前,先调用 。

lib/main.dart
// Also import Realm schema and Flutter widgets
import 'package:flutter/services.dart';
import 'package:realm/realm.dart';
import 'dart:io';
Future<Realm> initBundledRealm(String assetKey) async {
final config = Configuration.local([Car.schema]);
final file = File(config.path);
if (!await file.exists()) {
final realmBytes = await rootBundle.load(assetKey);
await file.writeAsBytes(
realmBytes.buffer
.asUint8List(realmBytes.offsetInBytes, realmBytes.lengthInBytes),
mode: FileMode.write);
}
return Realm(config);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final realm = await initBundledRealm("assets/bundle.realm");
runApp(const MyApp());
}

在大多数情况下,您不应捆绑同步域。 如果捆绑域的上次更新时间早于客户端最大离线时间,则用户在首次打开捆绑域文件时会遇到客户端重置。 客户端重置会导致应用程序从应用程序后端下载的完整状态。 这就抵消了捆绑域文件的优势。

您可以使用同步订阅向应用程序填充数据,而不是捆绑同步 Realm。 如果使用同步订阅添加数据,则无需担心数据早于客户端最大在线时间,同时可利用 Flexible Sync 的修剪功能。 要了解有关使用同步订阅的更多信息,请参阅管理同步订阅。

仅当您的使用案例满足以下条件时,才应捆绑同步域:

  • 您可以确保用户拥有的应用程序版本附带捆绑的同步 Realm,该 Realm 创建时间晚于客户端最大离线时间。

  • 初始捆绑数据非常大,并且应用程序是在互联网带宽有限的情况下使用的,因此使用同步订阅下载初始数据会花费太长时间。

  • 所有应用用户都具有查看捆绑包中包含的数据的后端权限。 如果用户没有查看此数据的权限,则当域通过补偿写入错误与 Atlas 同步时,该数据将从其设备中删除。

要捆绑同步 Realm,请执行以下操作:

  1. 连接到您的 App Services App 并对用户进行身份验证。

  2. 将订阅添加到 Realm。 您需要订阅才能写入同步 Realm。

  3. 将数据添加到同步 Realm。

  4. 等待所有本地更改与 Device Sync 服务器同步。

  5. 使用Realm.writeCopy()创建同步域的新版本。您 必须 使用 Realm.writeCopy() 捆绑同步域 ,因为该方法会删除将域与用户关联的元数据,而其他用户也可以通过这些元数据打开该域文件。

print("Bundling synced realm");
// You must connect to the Device Sync server with an authenticated
// user to work with the synced realm.
final app = App(AppConfiguration(APP_ID));
// Check if current user exists and log anonymous user if not.
final user = app.currentUser ?? await app.logIn(Credentials.anonymous());
final config = Configuration.flexibleSync(user, [Car.schema]);
final realm = Realm(config);
// Add subscription that match the data being added
// and your app's backend permissions.
realm.subscriptions.update((mutableSubscriptions) {
mutableSubscriptions.add(realm.all<Car>());
});
await realm.subscriptions.waitForSynchronization();
// Add data to realm
realm.write(() {
realm.add(Car(ObjectId(), "Audi", model: 'A8'));
realm.add(Car(ObjectId(), "Mercedes", model: 'G Wagon'));
});
// Sync changes with the server
await realm.syncSession.waitForUpload();
await realm.syncSession.waitForDownload();
// Create new configuration for the bundled realm.
// You must specify a path separate from the realm you
// are copying for Realm.writeCopy() to succeed.
final bundledConfig = Configuration.flexibleSync(user, [Car.schema],
path: 'sync_bundle.realm');
realm.writeCopy(bundledConfig);
print("Bundled realm location: " + bundledConfig.path);
realm.close();

创建捆绑 Realm 后,请按照上述在生产应用程序中捆绑 Realm 文件从捆绑 Realm 文件中打开 Realm部分的说明进行操作。

后退

删除 Realm

在此页面上