更改对象模型 - SwiftUI
概述
更新对象模式时,必须递增模式版本并执行迁移。 您可以在应用程序的主要版本之间更新对象模式。
有关如何实际执行迁移的信息,请参阅:更改对象模型。
本页重点介绍如何在 SwiftUI 视图中使用迁移的数据。
将迁移的数据与 SwiftUI 结合使用
要执行迁移,请执行以下操作:
更新模式并根据需要写入迁移区块
在初始化 Realm 时,指定使用此迁移逻辑和/或更新模式版本的Realm.Configuration 。
在这里,您有几个选项来传递配置对象。 您可以:
将配置设置为默认配置。 如果没有通过环境注入或作为参数显式传递配置,属性包装器将使用默认配置。
使用环境注入将此配置提供给层次结构中使用 Realm 的第一个视图
向采用配置对象(例如
@ObservedResults
或@AsyncOpen
的 Realm 属性包装器显式提供配置。
例子
例如,您可能想要向现有对象添加属性。我们可以向 DoggoDB 中的Dog
对象添加一个favoriteTreat
属性:
var favoriteTreat = ""
将新属性添加到模式后,必须递增模式版本。您的Realm.Configuration
可能如下所示:
let config = Realm.Configuration(schemaVersion: 2)
在层次结构中第一个需要此配置的视图可以访问的位置声明此配置。在@main
应用入口点上方进行声明,可使其在任何地方可用,但也可以将其放在首次打开 Realm 的文件中。
设置默认配置
您可以在 SwiftUI 应用程序中设置默认配置,就像设置任何其他 Realm Swift 应用程序一样。通过将新的 Realm.Configuration 实例分配给Realm.Configuration.defaultConfiguration类属性来设置默认 Realm 配置。
// Open the default realm let defaultRealm = try! Realm() // Open the realm with a specific file URL, for example a username let username = "GordonCole" var config = Realm.Configuration.defaultConfiguration config.fileURL!.deleteLastPathComponent() config.fileURL!.appendPathComponent(username) config.fileURL!.appendPathExtension("realm") let realm = try! Realm(configuration: config)
将配置对象作为环境对象传递
声明配置后,您可以将其作为环境对象注入到层次结构中第一个打开 Realm 的视图中。如果您使用@ObservedResults
或@ObservedRealmObject
属性包装器,这些视图会隐式打开一个 Realm,因此它们也需要访问此配置。
.environment(\.realmConfiguration, config)
如果您的应用程序使用本地 Realm 或同步 Realm,则层次结构中打开 Realm 的第一个视图会有所不同,具体取决于您使用的应用程序是否启用了同步。
如果没有同步,您可以将 Realm 配置环境对象直接传递给LocalOnlyContentView
:
.environment(\.realmConfiguration, config)
它使用以下内容隐式打开一个 Realm:
struct LocalOnlyContentView: View { // Implicitly use the default realm's objects(Dog.self) Dog.self) var dogs ( var body: some View { if dogs.first != nil { // If dogs exist, go to the DogsView DogsView() } else { // If there is no Dog object, add one here. AddDogView() } } }
但是,当您的应用使用同步时,您的 Realm 会显式使用@AsyncOpen
或@AutoOpen
属性包装器:
/// 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. 4000) var asyncOpen (appId: flexibleSyncAppId, timeout: 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) } } }
因此,您必须将环境对象传递给显式打开 Realm 的视图。 在本例中, OpenFlexibleSyncRealmView
。
要记住的重要一点是,确保将包含迁移逻辑的Realm.Configuration
传递给任何隐式或显式打开 Realm 的视图层次结构。
将更新的配置显式传递给 Realm SwiftUI 属性包装器
您可以将配置对象显式传递给接受配置对象(例如@ObservedResults
或@AutoOpen
的 Realm SwiftUI 属性包装器。 在这种情况下,您可以将其直接传递给@ObservedResults
中的DogsView
。
// Use a `config` that you've passed in from above. Dog.self, configuration: config) var dogs (