swift - 从 Realm 数据库读取数据 (Swift)

标签 swift database synchronization realm

我是 Realm 数据库的新手,我需要一种从 Realm 云读取数据的方法,但来自两个不同的应用程序项目。我尝试实现此目的的方法是使用查询同步 Realm 。目前,我正在使用单个 Realm 用户在一个应用程序中写入数据,并使用同一 Realm 用户从另一个应用程序读取数据。问题是从第二个应用程序(用于读取的应用程序)进行查询不会返回任何 Realm 对象(我还注意到用户标识符与第一个应用程序不同,并且用户权限为零。

我尝试直接从 RealmStudio 设置权限,因为文档对于如何从代码设置权限并不精确

func openRealm() {
    do {
        realm = try Realm(configuration: SyncUser.current!.configuration())
        let queryResults = realm.objects(*className*.self)
        let syncSubscription = queryResults.subscribe()
        let notificationToken = queryResults.observe() { [weak self] (changes) in
            switch (changes) {
            case .initial: print(queryResults)
            case .error(let error): print(error)
            default: print("default")
            }
        }
        for token in queryResults {
            print(token.tokenString)
        }
        syncSubscription.unsubscribe()
        notificationToken.invalidate()
    } catch {
        print(error)
    }
}

此函数打印一个应用程序项目中的数据,但在同一用户登录的另一个应用程序项目中使用,并且在项目中引用了相同的classFile,但事实并非如此。 (请注意,SyncUser.current.identifier 也不同

最佳答案

有几个问题。

其中一些调用是异步的,并且您问题中的代码在数据同步(检索)之前超出了范围。最重要的是代码比互联网更快,您需要围绕异步调用设计应用程序的流程;在数据可用之前不要尝试使用该数据。

例如

    let notificationToken = queryResults.observe() { [weak self] (changes) in
       //here is where results are fully populated
    }

    // this code may run before results are populated //
    for token in queryResults {
        print(token.tokenString)
    }

此外,let notificationToken 是一个本地变量,在填充结果之前就会超出范围。

这些问题非常容易解决。第一个是在等待填充结果时保持通知 token 处于事件状态,第二个是在闭包内处理结果,因为此时它们是有效的。

var notificationToken: NotificationToken? = nil //a class var

func openRealm() {
    do {
        let config = SyncUser.current?.configuration()
        let realm = try Realm(configuration: config!)
        let queryResults = realm.objects(Project.self)
        let syncSubscription = queryResults.subscribe(named: "my-projects")
        self.notificationToken = queryResults.observe() { changes in
            switch changes {
            case .initial:
                print("notification: initial results are populated")
                queryResults.forEach { print($0) }
            case .update(_, let deletions, let insertions, let modifications):
                print("notification: results, inserted, deleteed or modified")
                insertions.forEach { print($0) } //or mods or dels
            case .error(let error):
                fatalError("\(error)")
            }
        }
    } catch {
        print(error)
    }
}

deinit {
   self.notificationToken?.invalidate()
}

保持该 token (及其相应代码)有效的另一个好处是,当有进一步的更改时,您的应用程序将收到通知。因此,如果添加另一个项目,“更改”部分中的代码将运行并显示该更改。

关于swift - 从 Realm 数据库读取数据 (Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57575528/

相关文章:

ios - swift Kingfisher 和 MPMediaItemArtwork

ios - 在 firebase 问题中手动输入数据

mysql - 优化此 SQL 查询?

multithreading - 什么是新手的原子操作?

database - magento:生产、登台和开发之间的数据库同步

ios - 从 AppDelegate 调用委托(delegate)函数不起作用

swift - 现在 Swift 4 中的 filePrivate 有什么意义?

database - 主设备丢失且有效转储不存在(SYBASE ASE 15.0)

android - 如何在android中使用sqlite数据库创建表?

c++ - 在线程中等待一段时间,或者直到条件发生