Search code examples
swiftuimockingrealmswiftui-previewsrealm-ios

SwiftUI Previews w/Mock Realm


I am running into a problem trying to use an in memory realm configuration with previews. When the preview executes it returns an error. The diagnostics gives the following error:

MessageError: Connection interrupted

I have the following class defined to mock the realm data.

class MockRealms {
   static var previewRealm: Realm {
      get {
         var realm: Realm
         let identifier = "previewRealm"
         let config = Realm.Configuration(inMemoryIdentifier: identifier)
         do {
            realm = try Realm(configuration: config)
            try realm.write {
               for category in Categories.allCases {
                  _ = Category(name: category.rawValue)
               }
            }
            try realm.write {
               _ = Settings(type: .fixed, int: 3.375, dp: 25.0, term: 30)
            }
            return realm
         } catch let error {
            fatalError("Error: \(error.localizedDescription)")
         }
      }
   }
}

In the view we are using the @ObservedResults to get the categories from the Realm.

struct PropertyListView: View {
   @ObservedResults(Category.self) var categories
   @Binding var showInfo: Bool
   @Binding var showInfoButton: Bool
   @Binding var showGuide: Bool
   @Binding var showGuideButtton: Bool

   var body: some View {
      NavigationView {
         ScrollView {
            VStack {
               ForEach(categories) { category in
                  PropertyCategoryView(category: category)
               }
            }
         }
      }
      .navigationBarTitle("Property List")
      .navigationBarBackButtonHidden(false)
   }
   .navigationViewStyle(.stack)
} 

The preview section is as follows:

struct PropertyListView_Previews: PreviewProvider {
   static var previews: some View {
      Group {
         PropertyListView(showInfo: .constant(false), showInfoButton:
            .constant(true), showGuide: .constant(false), showGuideButton:
            .constant(false))
            .environment(\.realm, MockRealms.previewRealm)
         PropertyListView(showInfo: .constant(false), showInfoButton:
            .constant(true), showGuide: .constant(false), showGuideButton:
            .constant(false))
            .environment(\.realm, MockRealms.previewRealm)
            .preferredColorScheme(.dark)
      }
   }
}

Any help would be most appreciated.


Solution

  • On the main content view I call the PropertyListView with an environment setting realmConfiguration and pass that into the PropertyListView. So I changed the PreviewProvider to pass simply the in-memory Realm configuration and then everything seems to work just fine.

    struct PropertyListView_Previews: PreviewProvider {
       static var previews: some View {
          Group {
             PropertyListView(showInfo: .constant(false), showInfoButton:
               .constant(true), showGuide: .constant(false), showGuideButton:
               .constant(false))
               .environment(\.realmConfiguration, Realm.Configuration(inMemoryIdentifier: "previewRealm", schemaVersion: 1))
            PropertyListView(showInfo: .constant(false), showInfoButton:
               .constant(true), showGuide: .constant(false), showGuideButton:
               .constant(false))
               .environment(\.realmConfiguration, Realm.Configuration(inMemoryIdentifier: "previewRealm", schemaVersion: 1))
               .preferredColorScheme(.dark)
         }
      }
    

    }

    With Realm changing almost every other day it is like walking on quicksand. It is a wonderful DB for mobile development because they are constantly making it better, but boy you really have to stay on top of the changes.