T
T
Tkas2018-12-07 22:39:41
iOS
Tkas, 2018-12-07 22:39:41

Linking a view model to a view controller using closures. Is this approach correct in MVVM?

In my application, a cell is removed from the collectionView after a long press on it in the view controller. The deletion code is written in the view model and looks like this:

func deleteFood(forIndexPath indexPath: IndexPath, completion: @escaping ([FoodBySections], [FoodBySections]) -> ()) {
        let objectToDeleteName = self.foodBySections[indexPath.section][indexPath.row].name!
        
        let oldData = foodBySections
        CoreDataHelper.sharedInstance.deleteFoodFromFridge(foodName: objectToDeleteName)
        foods = CoreDataHelper.sharedInstance.fetchFoods()
        //newData
        foodBySections = FoodBySections.split(foods: foods!)
        
        completion(oldData, foodBySections)
    }

The controller code looks like this:
@objc func deleteFood(gesture: UILongPressGestureRecognizer!) {
        if gesture.state != .ended {
            return
        }
        
        let point = gesture.location(in: self.collectionView)
        
        if let indexPath = self.collectionView?.indexPathForItem(at: point) {
            self.foodViewModel?.deleteFood(forIndexPath: indexPath, completion: { [weak self] (oldData, newData) in
                guard let self = self else { return }
                self.collectionView.animateItemAndSectionChanges(oldData: oldData, newData: newData)
            })
        }
    }

Thus, we received the necessary data to update the collectionView through closures. Is this approach correct in MVVM? Or is it always necessary to use reactive anyway?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vyacheslav Beltyukov, 2018-12-13
@Tkas

I have had experience using MVVM without reactive. A bit longer code, but overall ok. Most of the reactivity is redundant if you only need binding.
As for this particular code, all the same, in the MVVM paradigm, it is not necessary to associate the user's action with the result. That is, you have a separate method deleteFood(IndexPath)and a separate

var animatableChanges: ((OldData, NewData) -> Void)?
where View can put its binding. This approach allows the ViewModel to update the view when it sees fit, and on the other hand, keep the code of all bindings in one place (for example, in a special method called from viewDidLoad).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question