打开同步 Realm - Flutter SDK
本页介绍如何使用 Device Sync 打开同步域。要了解如何打开和配置非同步 Realm,请参阅打开和关闭 Realm。
开始之前
在 Flutter 应用程序中使用 Flexible Sync 打开域之前:
在后端配置Flexible Sync 。 您必须在后端配置 Flexible Sync,然后才能将其与客户端应用程序一起使用。
对客户端项目中的用户进行身份验证。
打开同步 Realm
要打开同步域,请将登录用户、 Realm 对象模式列表以及其他可选命名参数传递给 Configuration.FlexibleSync() 构造函数。此构造函数返回 FlexibleSyncConfiguration 。然后,将FlexibleSyncConfiguration
传递给 Realm () 打开域的一个实例。打开域后,数据会在背景与App Services同步。
final currentUser = await app.logIn(credentials); final config = Configuration.flexibleSync(currentUser, [Tricycle.schema], path: 'flex.realm'); final realm = Realm(config);
打开同步域后,请配置和托管同步订阅。
下载更改后打开 Realm
Atlas App Services要在打开 Realm 时与 同步所有数据,请使用异步方法 Realm.open() 。该操作会在返回 Realm 之前同步所有可用数据。
首次打开时, Realm.open()
会下载与您的同步订阅匹配的所有数据。 后续打开仅下载最新更改。 根据初始 域 大小和设备未同步时对 数据集 的 更新,首次打开时性能可能会较慢,但后续打开时可能会更快。
如果客户端应用程序处于脱机状态,则无法解析Realm.open()
。 在使用Realm.open()
之前,您应该检查设备是否已连接到互联网。 如果设备未连接到互联网,您仍然可以使用Realm()
立即打开一个 Realm,并在互联网连接可用时在后台同步数据。
// Helper function to check if device is connected to the internet. Future<bool> isDeviceOnline() async { // ...logic to check if device is online } final config = Configuration.flexibleSync(currentUser, [Tricycle.schema]); // Only use asynchronous open if app is online. late Realm realm; if (await isDeviceOnline()) { // If the device is online, download changes and then open the realm. realm = await Realm.open(config); } else { // If the device is offline, open the realm immediately // and automatically sync changes in the background when the device is online. realm = Realm(config); }
要跟踪同步状态,请传递 ProgressCallback 为可选的命名参数onProgressCallback
。
double progressEstimate = -1; final realm = await Realm.open(config, onProgressCallback: (syncProgress) { progressEstimate = syncProgress.progressEstimate; print('Sync progress: ${progressEstimate * 100}% complete.'); if (progressEstimate == 1.0) { // Transfer is complete } });
提示
如果要在打开域后配置进度通知,请使用SyncSession.getProgressStream。
为了能够取消正在进行的同步,请将 CancellationToken 可选命名参数cancellationToken
的实例。调用 CancellationToken.cancel() 取消同步。
final token = CancellationToken(); // Cancel the open operation after 30 seconds. // Alternatively, you could display a loading dialog and bind the cancellation // to a button the user can click to stop the wait. Future<void>.delayed( const Duration(seconds: 30), () => token.cancel(CancelledException( cancellationReason: "Realm took too long to open"))); // If realm does not open after 30 seconds with asynchronous Realm.open(), // open realm immediately with Realm() and try to sync data in the background. late Realm realm; try { realm = await Realm.open(config, cancellationToken: token); } on CancelledException catch (err) { print(err.cancellationReason); // prints "Realm took too long to open" realm = Realm(config); }
例子
Realm() 与 Realm.open()
本部分将比较您可能希望使用Realm()
和Realm.open()
在应用程序中打开域的场景示例。
考虑一个允许用户记录并保存他们最喜欢的食谱的应用程序。 您可能希望为用户提供创建新菜谱的选项,而无需等待下载更新,即使用户处于离线状态也是如此。 在这种情况下,最好Realm()
。 用户可以离线操作,但当他们下次建立网络连接时,应用程序会同步他们的食谱。
考虑一个具有平板电脑和手机版本的游戏应用。 用户同时在桌面和手机上玩游戏。 用户在平板电脑上前进了三个级别。 随后,用户在手机上打开游戏。 在这种情况下, Realm.open()
是打开 Realm 的更好方法。 由于Realm.open()
在返回域之前同步数据,因此它可以确保用户的进度在开始使用应用程序之前在手机上同步,即使初始加载时间可能较慢。
配置 Realm
有关常规 域 配置选项的更多信息,请参阅配置 Realm。
要使用其他属性处理同步域中的错误,请参阅处理同步错误。
关闭 Realm
使用完同步 Realm 后,将其关闭以防止内存泄漏。
realm.close();