M0TRIX
M0TRIX

Reputation: 253

mvvm pattern in this style of coding is meanless?

I have developed my own project with MVC pattern and trying to convert to MVVM pattern, but sometimes I think its getting worse and meanless.

This is a part of my code. I have controller, model and one view-model like below:

struct FAQ: Mappable {        
    var id: String?
    var question: String?
    var answer: String?
    var datalist: [FAQ]?
    //var datalist: [Any]?

    mutating func mapping(map: Map) {
        id <- map["id"]
        question <- map["question"]
        answer <- map["answer"]
        datalist <- map["data"]
    }
}

class learningViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var faqLable: UILabel!
    @IBOutlet weak var learningLable: UILabel!
    @IBOutlet weak var uiviewHeader: UIView!
    @IBOutlet weak var barRight: UILabel!
    @IBOutlet weak var barLeft: UILabel!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var backImage: UIImageView!

    var learningRequestSession: URLSessionDataTask?
    let address = Domains.address
    var objectData = faqViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        objectData.faqFunc {
            self.setup()
        }
        setup()

    }

    override func viewWillAppear(_ animated: Bool) {
        tableView.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectData.objectData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "faqCell", for: indexPath) as! customViewCellTableViewCell

        //cell.faqIcon.image = UIImage(named: "question")
        cell.faqTitle.text = objectData.objectData[indexPath.row].question
        cell.faqBody.text = objectData.objectData[indexPath.row].answer

        return cell            
    }
...
}

and this is view-model class:

class faqViewModel {
    var objectData = [FAQ]()

    init(faq: [FAQ]) {
        self.objectData = faq
    }

    init() {}

    func faqFunc(complition: @escaping () -> () ) {        
        let url = URL(string: "\(address)faq/getdata")
        print(url!)

        URLSession.shared.dataTask(with: url!) { (data, response, err) in
            if let content = data {
                do {
                    let json = try! JSONSerialization.jsonObject(with: content, options: .mutableContainers) as Any

                    let mapper = Mapper<FAQ>().map(JSONObject: json)

                    self.objectData = (mapper?.datalist.map({ $0}))!
                } catch {
                    print(err)
                }
            }
        }.resume()
    }
}

faqFunc function used to be in controller class in MVC pattern.

I have moved it to view-model in this pattern. So I feel I am doing it wrong or MVC was better...!

Upvotes: 0

Views: 194

Answers (2)

fewlinesofcode
fewlinesofcode

Reputation: 3082

Some of MVC problems are well described in Dave DeLongs blog.

I agree with him, that MVC, in some cases may lead to:

  1. Massive View Controllers (View logic, business logic and networking are often placed in *ViewController classes which grow, sometimes enormously.

  2. Incapsulation violation (e. g. Passing data to ViewController in segue and so on)

  3. Testability. MVC usually requires writing integration tests, which are hard to maintain and require very good knowledge of UIKit

MVVM

It is worth of saying, that MVVM is basically a fancy MVC.

MVVM is an attempt to address some flaws of the MVC pattern. It improves separation of concerns, makes logic somehow clearer. No more massive view controllers (with proper usage). IMHO, the best benefit of the MVVM is Testability. Now we have ViewModel, object that contains all view-related data. So writing tests doesn't require integration testing anymore. But using MVVM usually connected to some kind of reactive programming. Which, itself, has hidden pitfalls and steep learning curve.

MVVM Pros

  1. Better testability
  2. Better separation of concerns
  3. Getting rid of Massive View Controllers
  4. It kinda fits CocoaTouch MVC paradigm

There's more, I guess

MVVM Cons

  1. Using reactive frameworks requires "mindset" change and, as a result - steep learning curve
  2. It is easy to get model and view out of sync
  3. Easy to make mistake in observing logic

And more

Conclusions

MVVM is a nice tool which, when used properly, fixes some MVC flaws and gives production benefits. MVVM requires some effort and best practices learning. But, before diving into it I suggest to read Dave DeLongs blog series "A better MVC" and remember, that MVC is a native Apple pattern, and by implementing it you stay "safe" from big surprises when SDK is updated.

P.S. I am a big fan of proper MVVM usage, but improper usage frightens me sometimes.

Upvotes: 2

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 120002

View model is a kind mini model for used within a view. So you bind view attributes to it and mange changes in each of them:

View changed -> view-model updates

View-Model changed -> view updates

The faqViewModel class you wrote is a kind of APIRequestLoader and not belongs to view-model. For more information, I suggest you to do some research about Clean Swift Architecture and Swift Viper Architecture and if you want to learn more about how to decouple network request from other parts of the app, This WWDC 2018 session is a good option to watch.

Upvotes: 1

Related Questions