swift - 如何在 SwiftUI 列表中显示 Realm 结果?

标签 swift realm swiftui

我已经能够将数据保存在 Realm 数据库中,但无法在 SwiftUI List 中显示结果。

我知道我有数据并且在控制台中打印结果没有问题。

有没有办法将 Realm Result 转换成可以在 SwiftUI List 上显示的格式?

import SwiftUI
import RealmSwift
import Combine

class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0

    override static func primaryKey() -> String? {
        return "name"
    }
}

class SaveDog {
    func saveDog(name: String, age: String) {
        let dog = Dog()
        dog.age  = Int(age)!
        dog.name = name

        // Get the default Realm
        let realm = try! Realm()

     print(Realm.Configuration.defaultConfiguration.fileURL!)

        // Persist your data easily
        try! realm.write {
        realm.add(dog)
        }

        print(dog)
    }
}

class RealmResults: BindableObject {
    let didChange = PassthroughSubject<Void, Never>()

    func getRealmResults() -> String{
        let realm = try! Realm()
        var results = realm.objects(Dog.self) { didSet 
 {didChange.send(())}}
        print(results)
        return results.first!.name
    }
}

struct dogRow: View {
    var dog = Dog()
    var body: some View {
        HStack {
            Text(dog.name)
            Text("\(dog.age)")
        }
    }

}

struct ContentView : View {

    @State var dogName: String = ""
    @State var dogAge: String = ""

    let saveDog = SaveDog()
    @ObjectBinding var savedResults = RealmResults()
    let realm = try! Realm()

    let dogs = Dog()

    var body: some View {
        VStack {
            Text("Hello World")
            TextField($dogName)
            TextField($dogAge)
            Button(action: {
                self.saveDog.saveDog(name: self.dogName, 
                age:self.dogAge)
//                self.savedResults.getRealmResults()
            }) {
                Text("Save")
            }
            //insert list here to show realm data

            List(0 ..< 5) { 
             item in
                Text(self.savedResults.getRealmResults())
            } //Displays the same thing 5 times
        }
    }
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
#endif

有些代码可能没有意义,因为我尝试了几种方法来查看是否有任何效果。

例如,这一行将在 ListView 中显示结果。

return results.first!.name

如果我只返回结果,则列表 TextView 中不会显示任何内容。

正如我在下面评论的那样,我将在有时间时尝试使用 ForEach 方法。这看起来很有希望。

最佳答案

您在 ListForEach 中传递的数据必须符合 Identifiable 协议(protocol)。

要么在 Realm 模型中采用它,要么使用 .identified(by:) 方法。


即便如此,如果数据发生变化,View 也不会重新加载。

您可以包装 Results 并使其成为 BindableObject,这样 View 就可以检测到更改并自行重新加载:

class BindableResults<Element>: ObservableObject where Element: RealmSwift.RealmCollectionValue {

    var results: Results<Element>
    private var token: NotificationToken!

    init(results: Results<Element>) {
        self.results = results
        lateInit()
    }

    func lateInit() {
        token = results.observe { [weak self] _ in
            self?.objectWillChange.send()
        }
    }

    deinit {
        token.invalidate()
    }
}

像这样使用它:

struct ContentView : View {

    @ObservedObject var dogs = BindableResults(results: try! Realm().objects(Dog.self))

    var body: some View {
        List(dogs.results.identified(by: \.name)) { dog in
            DogRow(dog: dog)
        }
    }

}

关于swift - 如何在 SwiftUI 列表中显示 Realm 结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56720441/

相关文章:

swift - 从 FIRUser 的 uid 中获取

xcode - CocoaPods 未在 Swift Parse Chat App 中安装 Alamofire

swift - Realm 中的索引属性

Android Realm.io 迁移 : Fallback to . deleteRealmIfMigrationNeeded()

ios - 如何在 WatchOS 6 中将 Crown 输入打印到控制台

ios - 修复 Swift simd 库中的错误(以及缺少文档?)

swift - 代表 RealmSwift 中的范围值?

ios - SwiftUI 中的属性 `@EnvironmentObject` 是什么意思?

SwiftUI - 如何访问列表中的数据

swift - Vapor Fluent 数据库事务不是原子的