0

I have a view model that's fetching some data from my API, and when I get data back, I'm setting it both in Realm and on two MutableProperties on the view model

        userService.getBrowseData().on(
            failed: { error in
                // TODO: Should call a closure the VC passes in here with an error to show
            }, value: { banners, lists in
                browseStoreService.store(banners: banners, lists: lists)

                self.banners.value = banners
                self.lists.value = lists
            }
        ).startWithCompleted { self.dataLoaded.value = true }

In my view controller, I'm getting a crash at the line where I instantiate and set a ListViewViewModel

disposable += viewModel?.dataLoaded.producer
    .observe(on: UIScheduler())
    .startWithValues { loaded in
        if loaded {
            guard let viewModel = self.viewModel else { return }

            self.carousel?.reloadData()

            for list in viewModel.lists.value {
                let view = ListView()
                view.viewModel = ListViewViewModel(list: list)
                view.listViewDelegate = self
                view.listItemViewDelegate = self

                scrollingStackView.addArrangedSubview(view: view)

                constrain(view) { view in
                    view.width == view.superview!.width
                    view.left == view.superview!.left
                    view.right == view.superview!.right
                }
            }
        }
}

The strange thing to me is that I'm just setting the data in realm, I'm not doing any additional fetch to get the data out of realm which would make sense to cause a crash, especially if the write hadn't finished.

In this case, I'm taking an array of banners and an array of lists in my response from the API, sending them into my storeService to set them in realm and assigning those same arrays to their respective MutableProperties.

Any idea what could be going here that would be causing this crash?

Edit:

The store function looks like this:

func store(banners: [Banner], lists: [List]) {
        let realm = try! Realm()

        do {
            try realm.write {
                realm.add(banners, update: true)
                realm.add(lists, update: true)
            }
        } catch {
            return
        }

        realm.refresh()
    }

and both models have a primary key of id

Zack Shapiro
  • 6,648
  • 17
  • 83
  • 151
  • I found a fix by doing the Realm write on the main thread. Not sure if there's a better way to solve this but that's one solution – Zack Shapiro Mar 22 '17 at 20:53
  • Even if it's just reading the properties, you cannot access Realm objects across threads. If it works on the main thread, that implies you must be storing a reference to a Realm object that was originally created on the main thread. You should be able to set an exception breakpoint to track the exact line of code that's causing the exception and see which Realm object is causing the issue. – TiM Mar 24 '17 at 19:33
  • Additionally, if you're not using it already, it might be worth checking out RxRealm (https://github.com/RxSwiftCommunity/RxRealm) for integrating Realm into reactive UIs this way. :) – TiM Mar 24 '17 at 19:34
  • I use ReactiveSwift, not RxSwift – Zack Shapiro Mar 24 '17 at 19:38

0 Answers0