Model-View-Controller (MVC) in iOS – A Modern Approach | raywenderlich.com

Learn some tips and tricks to go one up on MVC, Apple’s recommended architecture pattern, and modify your code to be scalable and extensible!


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1000705-model-view-controller-mvc-in-ios-a-modern-approach

I really enjoyed this article and have modified the loadJSONFile method for my own purposes to handle requests from a file or from a URL. I also added a localizedDescription to the NetworkError enum so I can respond to the user if necessary with a more meaningful description.

Really good stuff here for separation of concern.
I do have a couple of questions/comments about that method however,

  1. There is a simulateDelay parameter that is never used in the method so I am assuming it can be removed from the declaration. Is that correct?
  2. Relating to that, what is the purpose of the delaySeconds? Is that just to simulate loading from an external network source by delaying the call? If so, can I assume that I can remove it for my purposes and adjust the code accordingly in the body of the method by removing the .asyncAfter call? Is that correct?

Thanks in advance for any responses.

Great questions from @createch, looking forward to seeing some feedback on that.

The article and accompanying code are nice however, there were too many leaps-in-faith for me at my level. I would have appreciated a more detailed breakdown of how this was developed; get inside the mind of the developer when presented with the requirements, how one would stub it out, refactor it, etc.

It most likely would need to have multiple parts however, it would have been more instructive.

Thanks.

I’m wondering why you feel it’s a code smell to pass the model into a view for it to configure itself. Seems like that’s the best place to do it. UITableViewCells in particular…give it the model and let it figure out how to view it, not relying on some outside controller to know the view’s internals.

Why do you consider that a code smell?

@airjordan12345 Can you please help with this when you get a chance? Thank you - much appreciated! :]

I have arrived and with replies. Apologies, friends, I was not getting notifications for any comments on this article. :slight_smile:

Hi :slight_smile:

Thank YOU for your great questions and observations. Kudos on repurposing the method for your own purposes, at the end of the day it’s just a URL that loads data, so whether it’s remote or local makes no difference.

Regarding items 1 and 2, you are indeed correct that this is just used to simulate a network delay, and the parameter can be removed from the declaration as well as in the method. You can get rid of the asyncAfter as well as this just simulates a delay you may not need.

If you have any other Qs leave a message here, or drop me a mention in Twitter @iFeliLM :slight_smile:

@cyberkeyboarder

Hi and than you for your reply. I understand there may be some gaps or things not covered in as much detail in this tutorial.

Would you be kind enough to perhaps help me with some specific questions or things you’d like to know more about? I’d be more than happy to take the time and lend a hand where needed :slight_smile:


@shawnkc

Thanks for taking the time to read the article and for the excellent question.

At the end of the day it’s a po-tay-to / po-tah-to thing. I’ve done it both ways and seen it done both ways. If we were to go purely MVC, then the view should not really know anything about the model. Otherwise, to me, it becomes a mini view controller, or view+model combo.

You may read about making your views or components reusable, but in real-world usage you may have a cell so specific to a model that making it reusable is worthless or moot, and passing in the model for it to do it’s magic makes sense. The thing about passing the model in to cells that can get tricky is you may configure some things at a controller level, some at the cell level, and you now have multiple places where you tweak the cell.

From a very pure MVC perspective, configuring your cell (a view) would be a controller’s job, perhaps with the aid of a data source. In day-to-day usage, as with everything, using your own judgement and figuring out what’s best for this situation is totally ok.

A good middle ground could be protocols or base classes that allow you to reuse the cell while also knowing a bit about the model.

Let me know your thoughts or if you have any other Qs :slight_smile:

Hi @airjordan12345,

A. The article does a nice job stating what defines MVC.

B.

C. Then it jumps to describing the sample app.

What I am missing is “B”; How did you create the app to fit MVC?

Things like, did you actually plan out the M the V the C in advance?

If so, what are some approaches you took?

Or did you start pounding keys and refactor at some point, to make it fit

MVC? Or…, something else?

It would be great to see how you had a problem to solve, decided on a Pattern

(assuming you to this in advance), then piece by piece put it all together.

Learning the thought process in your approach.

Hope that makes sense - thanks for a great article!

Hi @cyberkeyboarder :slight_smile:

I think that’s where your own intuition and experience comes into play. You decide to add a new feature for your personal app, or get a story from your product owner at work, and are then thinking: “What do I have to do?”

Let’s assume you have to add a new tab to your application that reads data from a web service, and presents it in a collection view of custom cells.

This is where B, and your experience, come in. Right there you can probably break it down into needed a custom cell (view), an object for parsing data from the network (model), and your new controller that will host the collection view and run things (controller).

You may have very often heard clients say “I want an app that does this, this, and that!”. It’s not just the entire app was just thought of from the ground up as “MVC”, it’s further breaking down the whole “My app needs to do this” into components, chunks of work, and then going with whatever makes sense.

In essence if you follow a pattern like MVC or MVVM, you adhere to those constructs/conventions from the beginning. In the case of MVC you always aim to keep your model agnostic from your views and controllers, your views completely unaware of any models or business logic, and your controller just to run things without it becoming the model or the view layer.

It takes a bit of practice, but in my experience MVC is usually one of the cleanest patterns that’s simpler to wrap your head around. Another cool thing is Apple’s APIs are built around this as is sample code and documentation (for the most part).

If you have any further Qs, let me know :slight_smile: I’m still not getting notified about this topic :frowning: but will do my best to keep an eye out :smiley:

Thanks for your questions and time,
Feli :hugs:

I don’t know how, but I managed to port this tutorial to tvOS (consider that I am pretty new to this Swift/iOS/tvOS thingy). I brutally copied and pasted part of the storyboard (in XML) to the tvOS storyboard, fixed few colours and not only it compiles without any single error, it runs! I doubt it would have been possible with other samples in internet. Great job!

I have got only the issue that I can’t go back once in “Details” with the “Menu” button (it goes to Apple TV Home). Then the Navigation controllers aren’t really needed in tvOS, I believe. But it’s a great starting point, completely different from all the other tutorials and samples I have found until now (which I doubt they do respect the MVC at all at this point). Very interesting how it’s all initially managed from AppDelegate (where I suppose I may remove the navigation controllers. Something to think about). Great tutorial, thanks!

PS: If I may, one question: I often see in many examples the Table Views headers defined in Controller. Shouldn’t they be part of View? As for the “details” in this tutorial. Since it’s displaying some info I thought it should be part of View as well. How does that work?

Great question. the table headers or footers could be considered part of the view, yes, as they are essentially just views like a cell is. I usually add any UI, labels, outlets, and view-specific stuff for them in a XIB file, storyboard, and accompanying Swift subclass (if needed) for a header or footer. It’s quite normal, however, to see each project, company, or developer, take some liberties around the whole “MVC” pattern. So if it works out for you either way, go for it.

My only suggestion would be to ensure you’re not adding hundreds or thousands of lines of code to a controller, if you are making a header view subclass within your controller file I’d suggest putting it in its own file, but if it’s just the table view data source or delegate methods for headers/footers, then that should be ok as it doesn’t take up too many lines of code. :slight_smile:

1 Like

That’s indeed what I want to avoid, the “exploding” (massive) Controllers. Also since I am a beginner I’d love to start with the right foot. On the prototype app I made one year ago (then I had to drop everything due to family issues) I discovered, with horror, that to avoid to put much code in the controller (and also due to the parallelism in downloading the pictures for my collection views, which with closures, “didset” and all still drives me mad) I had put the data network loading in the views!

This tutorial and Design Patterns on iOS using Swift – Part 1/2 finally made me see the light! :smile:

I had an hard time understanding who the app’s API belonged to (M, V or C). Now I understand it’s none of the above… And your answer confirms I should finally be in the right direction at least regarding the views. I’d rather define a new class and display the data from there than to risk making a sort of OOP spaghetti code again! Thanks!

1 Like

This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!