Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

配置并打开 Realm - SwiftUI

在此页面上

  • 使用配置打开Realm
  • 打开同步 Realm
  • 在打开同步Realm之前下载更改
  • 离线打开同步 Realm

Swift SDK提供属性包装器,以便以SwiftUI友好的方式打开域 。

您可以:

  • 使用 defaultConfiguration隐式打开域或指定其他配置。 这适用于非同步和同步 Realm。

  • 始终在打开 同步 Realm 之前下载更改,这会在用户离线时超时。

  • 即使用户离线,也可打开同步 Realm 。 该 Realm 可能缺少最新数据。

当您使用@ObservedRealmObject@ObservedResults时,这些属性包装器会隐式打开一个域并检索指定的对象或结果。

// Implicitly use the default realm's objects(Dog.self)
@ObservedResults(Dog.self) var dogs

注意

@ObservedResults 属性包装器用于“SwiftUI 视图”。如果您想观察视图模型中的结果,请注册更改监听器

如果您未指定配置,这些属性包装器将使用defaultConfiguration 。 您可以全局设立defaultConfiguration ,应用中的属性包装器在隐式打开域时可以使用该配置。

您可以提供属性包装器用于隐式打开域的替代配置。 在应用中使用多个配置时,您可能需要执行此操作,例如同时具有SyncConfiguration和本地配置的情况。 为此,请创建显式配置。 然后,使用环境注入将相应配置传递给需要它们的视图。 将配置传递给属性包装器打开域的视图时,会使用传递的配置而不是defaultConfiguration

版本 10.12.0 新增

这些 SwiftUI 属性包装器打开同步 Realm 并填充视图。 这些属性包装器之间的主要区别在于用户是否必须在线:

  • 要在打开域之前从Atlas App Services应用下载更新,请使用@AsyncOpen属性包装器。 这要求用户具有网络连接。

  • 要在无论用户是否有网络连接的情况下都打开同步 Realm,请使用@AutoOpen属性包装器。 此属性包装器使开发者能够在其应用程序中设计离线优先功能。

提示

迁移到 Flexible Sync

您可以自动将Atlas App Services Device Sync模式从基于分区的同步迁移到Flexible Sync 。 这样,您就可以利用更具表现力和更精细的 Flexible Sync 订阅和权限来管理用户可以读取和写入的同步数据。 有关更多信息,请参阅从基于分区的同步迁移到 Flexible Sync。

对于需要从服务器获取最新信息的应用,请使用@AsyncOpen属性包装器,例如用户可以在多个设备上玩的带有实时排行榜的游戏应用。 这可确保用户永远不会使用包含过时数据的应用程序。

10.27.0版本新增

Realm Swift SDK版本10.27.0 添加了属性包装器的Flexible Sync版本,以使用SwiftUI打开Realm 。 您可以在打开域后在.onAppear中添加订阅查询。

@AsyncOpen(appId: flexibleSyncAppId, timeout: 4000) var asyncOpen

版本 10.28.0 新增内容

您可以使用initialSubscriptions参数创建FlexibleSyncConfiguration() 。 您可以使用此参数订阅配置中的 Flexible Sync 查询。 如果运行多次(示例,如果在定期重新加载的视图中),请在添加订阅之前检查订阅是否已存在。 再次添加相同的订阅会引发错误。

// Create a `flexibleSyncConfiguration` with `initialSubscriptions`.
// We'll inject this configuration as an environment value to use when opening the realm
// in the next view, and the realm will open with these initial subscriptions.
let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
let peopleSubscriptionExists = subs.first(named: "people")
let dogSubscriptionExists = subs.first(named: "dogs")
// Check whether the subscription already exists. Adding it more
// than once causes an error.
if (peopleSubscriptionExists != nil) && (dogSubscriptionExists != nil) {
// Existing subscriptions found - do nothing
return
} else {
// Add queries for any objects you want to use in the app
// Linked objects do not automatically get queried, so you
// must explicitly query for all linked objects you want to include.
subs.append(QuerySubscription<Person>(name: "people"))
subs.append(QuerySubscription<Dog>(name: "dogs"))
}
})

然后,将配置作为 环境对象传递给包含属性包装器的视图。

OpenFlexibleSyncRealmView()
.environment(\.realmConfiguration, config)

有关完整示例,请参阅SwiftUI快速入门。

要使用基于分区的同步打开域 ,请将partitionValue添加到属性包装器:

@AsyncOpen(appId: YOUR_APP_SERVICES_APP_ID_HERE, partitionValue: "", timeout: 4000) var asyncOpen

此 SwiftUI 属性包装器为当前用户启动Realm.asyncOpen() 。 属性包装器发布由AsyncOpenState 枚举表示的状态,您可以使用该状态来更新视图。

例子

此示例说明了使用@AsyncOpen在视图中打开域的一种方法。 首先,检查是否有用户或日志。 然后,尝试打开域,打开AsyncOpenState以显示适当的视图。 当域成功打开后,将其作为环境值注入以填充视图。

/// This view opens a synced realm.
struct OpenFlexibleSyncRealmView: View {
// We've injected a `flexibleSyncConfiguration` as an environment value,
// so `@AsyncOpen` here opens a realm using that configuration.
@AsyncOpen(appId: flexibleSyncAppId, timeout: 4000) var asyncOpen
var body: some View {
switch asyncOpen {
// Starting the Realm.asyncOpen process.
// Show a progress view.
case .connecting:
ProgressView()
// Waiting for a user to be logged in before executing
// Realm.asyncOpen.
case .waitingForUser:
ProgressView("Waiting for user to log in...")
// The realm has been opened and is ready for use.
// Show the content view.
case .open(let realm):
// Do something with the realm
UseRealmView(realm: realm)
// The realm is currently being downloaded from the server.
// Show a progress view.
case .progress(let progress):
ProgressView(progress)
// Opening the Realm failed.
// Show an error view.
case .error(let error):
ErrorView(error: error)
}
}
}
/// This view opens a synced realm.
struct OpenPartitionBasedSyncRealm: View {
// @AsyncOpen attempts to connect to the server and download remote changes
// before the realm opens. If there is no network connection,
// AsyncOpen cannot load changes and the realm does not open.
// We can use an empty string as the partitionValue here because we're
// injecting the user.id as an environment value from the LoginView.
@AsyncOpen(appId: YOUR_APP_SERVICES_APP_ID_HERE, partitionValue: "", timeout: 4000) var asyncOpen
var body: some View {
switch asyncOpen {
// Starting the Realm.asyncOpen process.
// Show a progress view.
case .connecting:
ProgressView()
// Waiting for a user to be logged in before executing
// Realm.asyncOpen.
case .waitingForUser:
ProgressView("Waiting for user to log in...")
// The realm has been opened and is ready for use.
// Show the content view.
case .open(let realm):
// Do something with the realm
UseRealmView(realm: realm)
// The realm is currently being downloaded from the server.
// Show a progress view.
case .progress(let progress):
ProgressView(progress)
// Opening the Realm failed.
// Show an error view.
case .error(let error):
ErrorView(error: error)
}
}
}

@AsyncOpen一样, @AutoOpen 会尝试在打开域之前下载更新。 但是,如果网络连接不可用,此方法则会打开一个包含设备上数据的域 。

对于用户处理可能过时的数据没有问题的应用程序,请使用此属性包装器,例如用户应该能够在设备上处理数据的笔记应用程序

@AutoOpen(appId: "app_id") var autoOpen
@AutoOpen(appId: "app_id", partitionValue: <partition_value>) var autoOpen

此 SwiftUI 属性包装器会在为当前用户打开 Realm 之前尝试下载更新。 如果没有互联网连接,此属性包装器则会返回给定appId和 Flexible Sync 或基于分区的同步配置的最新版本的本地 Realm 文件。

属性包装器发布由AsyncOpenState枚举表示的状态,您可以使用该状态来更新视图。 有关完整示例,请参阅上面的@AsyncOpen代码示例。

后退

更改对象模型