DEV Community

Fernando Martín Ortiz
Fernando Martín Ortiz

Posted on

What’s the model?

I teach iOS development as a side job. I work 9-5 (well, actually, it’s a bit earlier than that, since I’m working for an English company at this moment). After I finish working, three times a week, I teach iOS development to different people, for two hours. They are starting their careers, and they are developing their intuition about software engineering.

That’s really interesting from the point of view of somebody who has been in the industry for some years now. It’s good to remember how you started and what errors did you make at the beginning.

Today, I’m going to talk to you about an error I see over and over again, and recently, I think I reached a way of making people think about it, and reason about it.

Imagine you are developing an app for ordering food from restaurants:

  • You have a listwith different dishes and options.
  • You can add more units of any of the options you have in the list.
  • Each item in the list has the number of items of that type you’ve already added, it will let you add or sub any number of items at any moment.
  • Whenever you add food, there is a shopping cart or something like that at the bottom of the screen where you can see immediately updated the price of the food you’re buying.

Fairly simple, straightforward problem.

So, here is the thing. There are many ways on how to develop something like that. Imagine you’re using UIKit for now, and not SwiftUI. You would have tableView or collectionView cells for the items in the list, and you would sum to the amount that you have in the bottom.

This is how people tend to design these kind of apps when they start:

  • They detect the event to add more items of a certain type.
  • They check the label in the cell to know how many items of that type they have already added.
  • They add one to that number.
  • They update the label in the cell.

And they have similar solutions for the different parts of the UI in this and similar problems. They rely on the UI as the source of truth.

So I started to ask them: What is the model?. I start any exercise with them in the same way. Regardless of how simple of complex a screen is, I start asking them: What is the model in this UI?

The other thing that’s related to this I use to tell them from the very beginning is: We are UI developers. As UI developers, our goal isn’t only to deliver delightful UIs with animations and beatiful graphics. Our goal is to ensure consistency between the model and the UI. The part about the UI is usually easily understandable. The part about the model is very hard to understand when you’re starting.

Our goal is to ensure consistency between the model and the UI. You have a UI, what is the model?

Top comments (1)

Collapse
 
thomas_girard_10c89f2431d profile image
Thomas Girard

Hey, really liked the lesson. This is exactly what separates good iOS devs from the ones who just ship stuff that breaks.

You nailed the core point. We are not UI developers. We are model first developers who happen to care about nice UIs. The UI is just a consumer of the model. If the model is wrong, the UI will fight you forever, or look correct on screen but be completely broken underneath.

That starting question, "What is the model?", is the single most important question you can ask any new dev on any screen, no matter how simple. Ask it from day one and it sticks.

Here is how I teach it at my day job, UIKit for now, moving to SwiftUI later.

First, ignore the UI completely for 30 seconds. Ask the team, if this screen did not exist, what data would this feature actually need to be useful? That is your model. The UI is just how we read and write that data.

Second, write it down, even if it is just in comments or a private struct. For your food ordering example, it is almost always:

struct OrderItem: Identifiable {
    let id = UUID()
    var dish: Dish
    var quantity: Int
}

struct Order: Equatable {
    var items: [OrderItem] = []
    var subtotal: Double {
        items.reduce(0) { $0 + $1.dish.price * Double($1.quantity) }
    }
    var totalWithTax: Double {
        // your tax logic here
    }
}
Enter fullscreen mode Exit fullscreen mode

Everything else, like UITableView, animations, bottom bar, and so on, is just a way to view this model or update it.

Third, the one rule I enforce. Whenever someone tries to check the label and add one, stop them and ask, what is the single source of truth for this quantity right now? If they say the label, we are in trouble. If they say the OrderItem in the array or the CartManager, we are on the right track.

This is exactly why we use Combine, RxSwift, or even just @Published in SwiftUI. The UI observes the model, never the other way around.

You are doing great work on the side. Keep hammering this concept. The moment someone argues but the label is so easy to update is the exact moment you know you have won, because they will never make that mistake again.

If you want, I can send you the slide I use for this, or the small exercise I give new hires where they have to draw the model before touching any code. Happy to share.

Keep it up.