mardi 18 décembre 2018

Realm design pattern using notifications

I'm scratching my head about the type of design pattern that I should use with Realm notifications.

My project has controllers where I have an observe() function in the viewDidLoad, which looks something like the following

let realm = try! Realm()

var queries: [QueryData] = [QueryData]();

let results = realm.objects(QueryData.self)

notificationToken = results.observe { [weak self] (changes: RealmCollectionChange) in
    switch changes {
    case .initial:
        results.forEach { diff in
            if !diff.isInvalidated {
                let newQuery = QueryData();
                newQuery.id = diff["id"] as? String ?? ""
                newQuery.title = diff["title"] as? String ?? ""
                queries.append(newQuery);
            }
        }

        self?.adapter.performUpdates(animated: true); //IGListKit trigger UI update

    case .update(_, _, _, _):
        self?.queries.removeAll()

        results.forEach { diff in
            if !diff.isInvalidated {
                let newQuery = QueryData();
                newQuery.id = diff["id"] as? String ?? ""
                newQuery.title = diff["title"] as? String ?? ""
                queries.append(newQuery);
            }
        }

        self?.adapter.performUpdates(animated: true); //IGListKit trigger UI update

    case .error(let error):
        // An error occurred while opening the Realm file on the background worker thread
        print("error")
    }
}

When something changes within the collection the code updates the UI. It works pretty sweet but this has the side effect of having my Model as part of the Controller. I use observers pretty much in every controller.

I was thinking of extracting the forEach part into a separate Model file and just return a [QueryData] to be used within the controller. Sadly, that results in two queries for the same thing (one for the observer and one within the model).

What would be a better pattern for such cases?

Aucun commentaire:

Enregistrer un commentaire