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

捆绑 Realm - Kotlin SDK

在此页面上

  • Overview
  • 按平台划分的 资产 Realm 位置
  • 捆绑非同步 Realm
  • 使用种子数据填充资产Realm
  • 在生产应用程序中捆绑并打开 Realm 文件
  • 捆绑同步 Realm
  • 使用种子数据填充资产Realm
  • 创建资产 Realm 的副本
  • 在生产应用程序中捆绑并打开同步的 Realm 文件

1.9.0 版本中的新增功能

Realm Kotlin SDK 支持将 Realm 文件与应用程序捆绑在一起。这使您能够在应用程序下载中使用种子数据预填充数据库。

提示

考虑初始数据回调或初始订阅

您还可以使用 InitialDataCallbackInitialSubscriptions 在应用程序首次打开 Realm 时向 Realm 添加数据。

Realm Kotlin SDK 会根据捆绑资产/资源的平台常规位置,查找包含种子数据的资产 Realm:

  • Android :通过 android.content.res.AssetManager.open(assetFilename)

  • Java虚拟机(JVM)Class<T>.javaClass.classLoader.getResource(assetFilename)

  • 达尔文NSBundle.mainBundle.pathForResource(assetFilenameBase, assetFilenameExtension)

创建 asset Realm 后,您必须将其放置在适当的位置。 如果在首次打开 Realm 时找不到资产 Realm, Realm.open() 失败并显示IllegalArgumentException

1
  1. 创建一个新的临时项目,以创建并使用种子数据填充资产领域。 此项目使用与生产应用程序相同的Realm 对象模式

  2. 打开包含要播种的数据的现有 Realm ,或创建新 Realm。 为资产领域设置一个特定名称,以便您可以通过名称来引用它,将其作为应用程序的初始数据源。

  3. 使用要包含在生产应用程序中的种子数据填充资产域。

    您可以使用Realm.configuration.path 获取资产 Realm 文件的路径。

// Open a local realm to use as the asset realm
val config = RealmConfiguration.Builder(schema = setOf(Item::class))
.name("asset.realm")
.build()
val assetRealm = Realm.open(config)
assetRealm.writeBlocking {
// Add seed data to the asset realm
copyToRealm(Item().apply {
summary = "Write an awesome app"
isComplete = false
})
}
// Verify the data in the existing realm
// (this data should also be in the bundled realm we open later)
val originalItems: RealmResults<Item> = assetRealm.query<Item>().find()
for(item in originalItems) {
Log.v("Item in the assetRealm: ${item.summary}")
}
// Get the path to the realm
Log.v("Realm location: ${config.path}")
assetRealm.close()

现在您已经拥有了 asset Realm,您可以将其移至生产应用程序中并在其中使用。

提示

Realm 跨 SDK 兼容

使用相同文件格式的 Realm 文件可跨 SDK 兼容。 如果您需要以编程方式创建资产Realm以与生产应用程序捆绑在一起,则可以使用Node.js SDK来轻松与CI管道集成。

您可以在 SDK 的变更日志中找到您的 SDK 版本支持的文件格式。 这可能类似于“文件格式:生成文件格式为 v23 的 Realm”。

2
  1. 将 asset Realm 文件的副本保存到生产应用程序中。您必须将此资产文件放在适合应用平台的位置。有关详细信息,请参阅按平台划分的资产领域位置。

  2. 创建生产应用程序可用于打开资产 Realm 的配置。将此配置中的initialRealmFile属性设置为您的资产 Realm 的名称。

    您可以选择为域提供文件,以便在打开sha256checkSum initialRealmFileRealm 文件时验证 Realm 文件的完整性。如果您在打开种子域时提供的校验和与计算出的资产文件校验和不匹配,则Realm.open()会失败并显示IllegalArgumentException

  3. 使用此配置,您可以打开捆绑的 asset Realm。 它包含您复制数据时资产领域中的数据。

// The config should list the bundled asset realm as the initialRealmFile
val bundledRealmConfig = RealmConfiguration.Builder(schema = setOf(Item::class))
.initialRealmFile("asset.realm")
.build()
// After moving the bundled realm to the appropriate location for your app's platform,
// open and use the bundled realm as usual.
val bundledRealm = Realm.open(bundledRealmConfig)
val bundledItems: RealmResults<Item> = bundledRealm.query<Item>().find()
for(item in bundledItems) {
Log.v("Item in the bundledRealm: ${item.summary}")
}
bundledRealm.close()

捆绑同步 Realm 可以减少用户在使用同步 Realm 时首次打开时必须下载的数据大小,但代价是增加应用的下载文件大小。 当您将 asset Realm 与应用程序捆绑在一起时,用户在打开该 Realm 时必须下载的唯一数据是自准备该 asset realm 以来发生的任何更改。

重要

捆绑同步 Realm

如果您的后端应用程序使用Flexible Sync ,则用户可能会在首次打开捆绑 Realm 文件时遇到客户端重置。 启用客户端最大离线时间(默认情况下启用客户端最大离线时间)时,可能会出现这种情况。 如果在用户首次同步之前生成捆绑 Realm 文件的时间超过了客户端最大离线时间设置指定的天数,则用户会遇到客户端重置。

执行客户端重置的应用程序会从应用程序后端下载 Realm 的完整状态。 这抵消了捆绑 Realm 文件的优势。 为防止客户端重置并保留 Realm 文件捆绑的优点,请执行以下操作:

  • 避免在捆绑同步 Realm 的应用程序中使用客户端最大离线时间。

  • 如果您的应用程序确实使用了客户端最大离线时间,请确保您的应用程序下载始终包含最近同步的 Realm 文件。 为每个应用程序版本生成一个新文件,并确保任何版本保持最新状态的时间都不会超过客户端最大离线时间天数。

如果应用程序使用Flexible Sync ,则可以使用初始同步订阅向数据填充应用程序,作为捆绑已同步 asset Realm 的替代方法。 对于初始订阅,您无需担心数据早于客户端最大离线时间。 要了解有关使用同步订阅的更多信息,请参阅订阅。

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

1
  1. 创建一个新的临时项目以创建和填充资产 Realm。 此项目使用与生产应用程序相同的Realm 对象模式

  2. 打开要用作资产 域 的同步 域

  3. 使用要包含在生产应用程序中的种子数据填充资产 Realm。您必须等待所有本地更改与 Device Sync 服务器同步。使用uploadAllLocalChanges()downloadAllServerChanges()确保所有同步进程均已完成。

val app = App.create(yourFlexAppId)
// Login with user that has the server-side permissions to
// read and write the data you want in the asset realm
val user = app.login(credentials)
// Create a SyncConfiguration to open a synced realm to use as the asset realm
val assetRealmConfig = SyncConfiguration.Builder(user, setOf(Item::class))
.name("asset.realm")
// Add a subscription that matches the data being added
// and your app's backend permissions
.initialSubscriptions{ realm ->
add(
realm.query<Item>("isComplete == $0", false), "Incomplete Items")
}
.build()
val assetRealm = Realm.open(assetRealmConfig)
assetRealm.subscriptions.waitForSynchronization(10.seconds)
assertEquals(SubscriptionSetState.COMPLETE, assetRealm.subscriptions.state)
assetRealm.writeBlocking {
// Add seed data to the synced realm
copyToRealm(Item().apply {
summary = "Make sure the app has the data it needs"
isComplete = false
})
}
// Verify the data in the existing realm
// (this data should also be in the bundled realm we open later)
val assetItems: RealmResults<Item> = assetRealm.query<Item>().find()
for(item in assetItems) {
Log.v("Item in the assetRealm: ${item.summary}")
}
// IMPORTANT: Sync all changes with server before copying the synced realm
assetRealm.syncSession.uploadAllLocalChanges(30.seconds)
assetRealm.syncSession.downloadAllServerChanges(30.seconds)
2

您必须从临时项目创建 asset realm 的副本,以便与生产应用程序捆绑在一起。

  1. 创建SyncConfiguration ,您的应用可使用该配置打开资产 Realm 的副本。将此配置中的initialRealmFile属性设置为您的资产 Realm 的名称。

    您可以选择为域提供文件,以便在打开sha256checkSum initialRealmFileRealm 文件时验证 Realm 文件的完整性。如果您提供的校验和与打开种子域时计算出的校验和不匹配,则Realm.open()将失败并显示IllegalArgumentException

    // Create a SyncConfiguration for the bundled copy.
    // The initialRealmFile value is the `name` property of the asset realm you're bundling.
    val copyConfig = SyncConfiguration.Builder(user, setOf(Item::class))
    .initialRealmFile("asset.realm")
    .build()
  2. 使用writeCopyTo()创建同步 Realm 的新版本。 您必须使用writeCopyTo()来捆绑同步 Realm。 此方法会删除将 Realm 与用户关联的元数据,从而允许其他用户打开 Realm 文件。

    使用Realm.configuration.path 获取复制的 Realm 文件的路径。

    // Copy the synced realm with writeCopyTo()
    assetRealm.writeCopyTo(copyConfig)
    // Get the path to the copy you just created.
    // You must move this file into the appropriate location for your app's platform.
    Log.v("Bundled realm location: ${copyConfig.path}")
    assetRealm.close()

现在您已经拥有 asset Realm 的副本,您可以将其移至生产应用程序中并在其中使用。

3
  1. 将 asset Realm 文件的副本保存到生产应用程序中。您必须将此资产文件放在适合应用平台的位置。有关详细信息,请参阅按平台划分的资产领域位置。

  2. 现在,您已拥有与应用程序捆绑在一起的 asset Realm 的副本,您可以使用创建的复制 Realm 配置将其打开。 它包含您复制数据时资产领域中的数据。

// After moving the bundled realm to the appropriate location for your app's platform,
// open and use the bundled realm as usual.
val copiedRealm = Realm.open(copyConfig)
// This should contain the same Items as in the asset realm
val copiedItems: RealmResults<Item> = copiedRealm.query<Item>().find()
for(item in copiedItems) {
Log.v("Item in the copiedRealm: ${item.summary}")
}
copiedRealm.close()

后退

加密 Realm