Swift 中的共享领域中的对象如何同步

How Are Objects Synced in a Shared Realm in Swift

在搜索 the documentation 之后,我最近了解到共享领域(我的应用程序的所有用户都可以在全球范围内使用)只能通过 Realm.asyncOpen 查询.例如,我有一个 /shared 领域,它对任何用户都具有只读访问权限。我尝试以通常的方式查询它,但它返回了零个对象。但是如果我这样查询它,它会起作用:

Realm.asyncOpen(configuration: sharedConfig) { realm, error in
  if let realm = realm {
    // Realm successfully opened
    self.announcements = realm.objects(Announcement.self)

    print(self.announcements)
    self.tableView.reloadData()

  } else if let error = error {
    print(error)
  }
}

此方法明显比通常的领域查询慢,因为它似乎是从服务器而不是本地、已经同步的领域获取数据。

这是否意味着下拉的对象永远不会存储在领域的本地副本中,而是在我每次访问它们时从 ROS 中查询?

换句话说,共享领域是否被拉取而不是同步?

a shared realm (globally available to all users of my app) can only be queried with Realm.asyncOpen

这是不正确的。如果用户对 Realm 只有 只读 访问权限,则必须使用 Realm.asyncOpen 获得。这就是 documentation you linked to states.

的明确含义

This method is visibly slower than a usual realm query since it appears to be fetching the data from the server instead of a local, already-synced realm.

几乎正确。是的,数据是从服务器获取的,但不是从头开始的整个领域。只有自上次 Realm 与您的本地副本同步以来的新数据。

Does this mean that the objects pulled down are never stored in the local copy of the realm, but are queried from the ROS each time I access them?

这个同步的 Realm 在本地持久保存,并将在应用程序启动时保留。

In other words, are shared realms pulled and not synced?

没有


退一步,让我们解释一下这里发生了什么。

如果您尝试同步打开只读同步领域,您会收到 "permission denied" 错误的原因是,在初始化时,将创建一个本地领域文件,执行写入操作以写入领域的架构(即立即创建数据库表、列和元数据)。但是,由于用户没有对 Realm 的写入权限,Realm 对象服务器 (ROS) 拒绝更改并触发您的全局错误处理程序,通知您您的用户试图非法修改文件。

asyncOpen 不会发生这种情况的原因是它是一个异步操作,因此不需要立即 给你一个有效的领域,所以它不需要通过将架构写入它来 "bootstrap" 它。相反,它从 ROS 请求 Realm 的最新状态,并在它在调用开始的时间点以其最新状态完全可用时将其返回给您。

也就是说,如果 Realm 的本地副本已经初始化了它的架构(即在成功 asyncOpen 调用之后),并且内存中的架构由默认架构或自定义对象定义Realm.Configuration 中指定的类型未更改,则不会尝试将架构写入文件。

这意味着在 asyncOpen 调用成功后的任何时候,只要您不介意可能没有最新版本,就可以同步访问 Realm 而无需经过 asyncOpen来自 ROS 的数据。

因此在您的情况下,您似乎只想使用 asyncOpen 来首次访问领域,因此您可以保持该状态(使用另一个领域或 NSUserDefaults)并检查它决定是否异步或同步打开 Realm。