How to use Realm with SwiftUI

后端 未结 2 1283
没有蜡笔的小新
没有蜡笔的小新 2020-12-13 16:53

I have been trying to figure out how to use Realm with SwiftUI. The problem is that SwiftUI and Realm both have a List type. When you import SwiftUI into your Realm model

2条回答
  •  孤城傲影
    2020-12-13 17:03

    @JustinMiller I created a ChannelsData class that I use to listen for changes in my chat channels from a Realm collection. I then update the UI by making the ChannelsData an @EnvironmentObject in my view. Here is what works for me in Xcode 11 GM Seed:

    final class ChannelsData: ObservableObject {
        @Published var channels: [Channel]
        private var channelsToken: NotificationToken?
    
    // Grab channels from Realm, and then activate a Realm token to listen for changes.
    init() {
        let realm = try! Realm()
        channels = Array(realm.objects(Channel.self)) // Convert Realm results object to Array
        activateChannelsToken()
    }
    
    private func activateChannelsToken() {
        let realm = try! Realm()
        let channels = realm.objects(Channel.self)
        channelsToken = channels.observe { _ in
            // When there is a change, replace the old channels array with a new one.
            self.channels = Array(channels) 
        }
    }
    
    deinit {
        channelsToken?.invalidate()
    }
    

    And then I use an @EnvironmentObject to grab the channels for my view:

    struct ChannelsContainerView: View {
    
        @EnvironmentObject var channelsData: ChannelsData
    
        var body: some View {
            List(channelsData.channels.indexed(), id: \.1.id) { index, _ in
                NavigationLink(destination: ChatView()) {
                    ChannelRow(channel: self.$channelsData.channels[index])
                }
            }
        }
    }
    

    Don't worry about the indexed() function in the List. But if you're curious, it comes from Majid's clever approach to creating flexible SwiftUI data storage classes here: https://mecid.github.io/2019/09/04/modeling-app-state-using-store-objects-in-swiftui/

    And if you're coming into the view from another view, be sure to add .environmentObject(ChannelsData()) to your view link (and also in your Previews) or it won't work.

提交回复
热议问题