037 iPhreaks Show – MVC

00:00
Download MP3

Panel Jaim Zuber (twitter Sharp Five Software) Pete Hodgson (twitter github blog) Charles Max Wood (twitter github Teach Me To Code Rails Ramp Up) Ben Scheirman (twitter github blog NSSreencast) Discussion 01:32 - Model View Controller (MVC) and Model View Presenter (MVP) Ruby on Rails Model View ViewModel (MVVM) MFC Knockout.js 14:20 - Implementing MVC in iOS Apps 16:46 - Designing Models Alistair Cockburn: Hexagonal Architecture Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans Ruby Rogues Episode #78: Hexagonal Rails with Matt Wynne and Kevin Rutherford Ruby Rogues Episode #61: Domain Driven Design (DDD) with David Laribee 28:32 - Models and the Controller Notifications 31:00 - Key-Value Observing (KVO) 35:48 - Delegates and Blocks Picks Mattt Thompson: Key-Value Observing (Pete) Alistair Cockburn: Hexagonal Architecture (Pete) Saul Mora - Design Patterns for Mobile Apps (Pete) New Spring: The Novel (Wheel of Time) by Robert Jordan (Chuck) Freelancing Q&A (Chuck) Next Week OS X Transcript PETE: I can’t believe I beat Ben Scheirman today. CHUCK: With a stick? PETE: No, he’s in the wrong state for that. CHUCK: Hey everybody and welcome to episode 37 of the iPhreaks Show. This week on our panel we have Jaim Zuber. JAIM: Hello from Minneapolis, where it’s a balmy 4°. CHUCK: Pete Hodgson. PETE: You just totally stole my thunder. I was going to complain about being cold in San Francisco, but it’s a lot warmer than that. Hello from not-so-frigid San Francisco. CHUCK: How cold is it in San Francisco? PETE: [Chuckles] Like, 32°. I don’t know, it feels like it’s freezing, but it’s probably not even 32°. Probably warmer than that, just cold for San Francisco. CHUCK: Charles Max Wood from DevChat.tv and it’s also 4° here. PETE: Okay, I’ll stop complaining. JAIM: Really? Or is it just dry cold? CHUCK: Yeah, it’s just dry cold here, too. We did get some snow. JAIM: There we go. PETE: It all makes sense now. JAIM: A little bit nicer. CHUCK: Yeah. Gives you something to do – go shovel snow, go skiing – we’re making people jealous now, I'm sure. PETE: I think I've been here once in San Francisco when it snowed, and it was like two or three flakes on the top of Twin Peaks, which is like the only really tall bit of San Francisco, and people drove their cars up there in the middle of the night to see these snowflakes fall [chuckles]. But it wasn’t like snowball fights; it was like four snowflakes. It was really exciting; it made my year. No skiing that year for us at San Francisco. CHUCK: Oh, come on. Alright. Anyway, so today on our [inaudible] we have MVC. JAIM: Alright, we’re talking MVC – an MVC extravaganza of sorts, I think. CHUCK: Yup. [Chuckles] PETE: Maybe we should start off with a definition. CHUCK: [Chuckles] A definition. Thanks, Josh. JAIM: That might take the entire episode, I think. PETE: With MVC, I always get really confused. So I know what MVC stands for: Model-View-Controller. And I kind of understand the principles quite well. But what I don’t get is the difference between MVC and MVP, and then it gets really confusing when you start talking about some of the other things out there. This is a long shot. Do either of you two know the difference between MVC and MVP? Because I definitely could not answer that if I have to save my life. CHUCK: I have a very vague idea of what it means, so I'm not even going to venture to try because I’ll probably get it wrong. One thing that I can say, though is that I've come to iOS programming from a very strong Rails background, and MVC in Rails and MVC in iOS are not the same. JAIM: Yup. CHUCK: I tend to think of iOS as more of an MVVM, because –. JAIM: I forgot about that one. CHUCK: The controller acts more like a view model or a view controller than it does, you know, a full-on controller.

Transcript

PETE: I can’t believe I beat Ben Scheirman today. CHUCK: With a stick? PETE: No, he’s in the wrong state for that. CHUCK: Hey everybody and welcome to episode 37 of the iPhreaks Show. This week on our panel we have Jaim Zuber. JAIM: Hello from Minneapolis, where it’s a balmy 4°. CHUCK: Pete Hodgson. PETE: You just totally stole my thunder. I was going to complain about being cold in San Francisco, but it’s a lot warmer than that. Hello from not-so-frigid San Francisco. CHUCK: How cold is it in San Francisco? PETE: [Chuckles] Like, 32°. I don’t know, it feels like it’s freezing, but it’s probably not even 32°. Probably warmer than that, just cold for San Francisco. CHUCK: Charles Max Wood from DevChat.tv and it’s also 4° here. PETE: Okay, I’ll stop complaining. JAIM: Really? Or is it just dry cold? CHUCK: Yeah, it’s just dry cold here, too. We did get some snow. JAIM: There we go. PETE: It all makes sense now. JAIM: A little bit nicer. CHUCK: Yeah. Gives you something to do – go shovel snow, go skiing – we’re making people jealous now, I'm sure. PETE: I think I've been here once in San Francisco when it snowed, and it was like two or three flakes on the top of Twin Peaks, which is like the only really tall bit of San Francisco, and people drove their cars up there in the middle of the night to see these snowflakes fall [chuckles]. But it wasn’t like snowball fights; it was like four snowflakes. It was really exciting; it made my year. No skiing that year for us at San Francisco. CHUCK: Oh, come on. Alright. Anyway, so today on our [inaudible] we have MVC. JAIM: Alright, we’re talking MVC – an MVC extravaganza of sorts, I think. CHUCK: Yup. [Chuckles] PETE: Maybe we should start off with a definition. CHUCK: [Chuckles] A definition. Thanks, Josh. JAIM: That might take the entire episode, I think. PETE: With MVC, I always get really confused. So I know what MVC stands for: Model-View-Controller. And I kind of understand the principles quite well. But what I don’t get is the difference between MVC and MVP, and then it gets really confusing when you start talking about some of the other things out there. This is a long shot. Do either of you two know the difference between MVC and MVP? Because I definitely could not answer that if I have to save my life. CHUCK: I have a very vague idea of what it means, so I'm not even going to venture to try because I’ll probably get it wrong. One thing that I can say, though is that I've come to iOS programming from a very strong Rails background, and MVC in Rails and MVC in iOS are not the same. JAIM: Yup. CHUCK: I tend to think of iOS as more of an MVVM, because –. JAIM: I forgot about that one. CHUCK: The controller acts more like a view model or a view controller than it does, you know, a full-on controller. That’s just my take on things. JAIM: [Crosstalk] all this, we have to start at the beginning. [Chuckles] CHUCK: That’s a very good place to start. JAIM: I think MVC has become such a convoluted term, depending on kind of what world do you come from. CHUCK: Ah-huh. JAIM: I mean like, from the Ruby world we’ve got, in the .NET, kind of copied the Ruby version of MVC –. PETE: Yeah, that’s true. JAIM: And that’s what everyone kinda uses for MVC. But if you go back, kind of a Smalltalk, MVC’s very different. It was designed to be kind of a thick client-type thing, and so the web stuff doesn’t really – the same patterns don’t apply. [Inaudible] client, like the model updates the view, or something like that, which makes no sense in the web world. But when people say MVC, it’s kind of what they're talking about. But the Apple view, is quite a bit different. So, if you're talking MVC in Rails aspect versus kind of Apple thing, it’s totally different. PETE: I guess the MVC, you know the UIKit MVC, is pretty much similar to the Smalltalk MVC – is that a good guess? JAIM: From my understanding, I don’t fully understand the Smalltalk one, but I know – I mean, with like Rails, .NET, the controller creates the model, hands it to the view. It’s like that guy in office space, you know? He takes the requirements, hands it to the engineers. But in iOS, you’ve got the controller talks the model, the model talks back to the controller, which doesn’t really make any sense in the web world, but that’s one pretty pertinent distinction when we’re talking about iOS-Apple stuff and more web-based MVCs. PETE: And the views talk back to the controllers as well, right? Which you would never get in – so you could be doing Rails or ASP.NET MVC, the view is just kind of a template that you kinda squirt data through, or at least it’s just something that takes the model that the controller has provided to it and uses it to display data to the screen as it were to render HTML. Whereas with Cocoa – I'm just gonna just call it different versions of MVC every time. With Cocoa MVC or UIKit MVC, the views are – when the user interacts with that view, the view kind of triggers events on the controller, so it’s much less of a one-way communication. CHUCK: So, with the Model-View-Controller, typically you have your view and your – even when you're talking about Model-View-Presenter, or Model-View ViewModel, the model and the view generally stay pretty much the same, have the same responsibilities. So the model basically contains all of your domain logic – in other words, if you're writing a banking app, then each model will have a different job relating to the banking app. Some of them may be users that are responsible for authentication; you might have other things that represent like line items in an invoice or a tally sheet or whatever – that does all of the logic. So it’s all of the math, all of the work, basically. And the view is responsible for displaying whatever it is that it gets from the presenter or view model or controller, in a way that people can interact with it. It manages the interactions; usually it just delegates the events from the interactions to something else like the presenter-controller, and it was ultimately responsible for the UI portion. And then the presenter is kind of the go-between, or the controller is the go-between between those. To give a little bit of context, the controller typically will determine which view or set of views to show, and it will also ultimately be responsible for – at least in Rails, and from what I can tell, in iOS – it’s responsible for actually returning the ultimate response. It’s responsible for coordinating the reaction to whatever happens. PETE: I think that’s the key concept to the controller is it’s the coordinator between parties. So, things happen in the model layer, or things happen in the view layer of the – or the view portion of this triad. The controller decides what to do in response to that interaction – maybe it will go to the model layer and ask it to do some things, and then it will get some stuff back out from the model or set of models and then ask the view to do its thing. JAIM: With Rails, the interaction between the models and the views are passive, right? The controller is always having to kind of pull stuff out of the models and put stuff into views and vice versa, whereas with some other frameworks you have data binding where the models and – well I guess with  MVVM, you have – ViewModels can be kind of bound directly to the view, so you use like a data binding technology to automatically update the ViewModel when someone interacts with the view. PETE: You know, this is ridiculous that I can’t remember this, but you can do that with iOS, right? You can do key-value observing and stuff like that, but it doesn’t feel like it’s actually that common to do that data binding thing automatically. I think, normally, you’d get the controller involved but maybe I'm making myself sound like an idiot on live broadcast by saying that. CHUCK: [Chuckles] From what I've done playing with iOS and things like that, yeah, typically what I see is that the view delegates things back to the controller and the controller does the coordination. So, yeah, I don’t see as much of the strict or the data binding that you see with MVVM. PETE: There's no reason you couldn’t do [inaudible]. I mean, key-value observing is pretty powerful, so you could have a view that observes a model and when the controller modifies the model, the view would automatically update it, so. But I think if you were going to do that, you’d want a ViewModel. You'd want a class that represents kind of the logical representation of the view, rather than a class that represents your domain concepts, which is what you were describing out of your [inaudible] model. JAIM: Right. That gets more into where you're talking about the MVP where you might have domain logic in your model, but maybe you have a name that you had to format a certain way or a date that might go kind of in the view and that’s more of a presenter; like it’s more of the MVP type. [Crosstalk] CHUCK: Now that we’re talking about this, yeah I tend to think of the Model-View-Presenter as more of the presenter is the go-between in every way for the model. So if you do any bindings to – like we’re talking about here in Model-View-Presenter, then you would actually bind to the presenter and the presenter would pass through to the model back. And so the view doesn’t know anything about the model; the only thing that it knows about is the presenter. PETE: And actually, in a lot of – I would argue, in most cases, the view doesn’t actually know about the presenter. Well, it doesn’t know about things like – the view shouldn’t really know about anything, in my opinion. The view should know about – you obviously need to tell the view, “Hey, when stuff happens, call this delegate or fire this event or whatever” but really, the view should be pretty dumb as to what it’s talking to. It shouldn’t really know what it’s talking to, because otherwise you have this circular [inaudible] where the views know about the controllers, and the controllers know about the views, and suddenly it’s very, very hard to tease those two apart. They kind of all get bound up together. CHUCK: The other issue that I've seen in views is that if you start putting the logic like that into the views, then what you wind up doing is you're blending new Y set up with logic, and sometimes then it’s hard to test or tease apart or debug. PETE: I think I have memories of when I was first starting with iOS programming. I had a real hard time with that, with trying to figure out where to put presentation logic. I think I started off doing things the way I used to do them really back in the day with MFC. It was this horrible C++ library for Windows programming. And with that library, you sub-classed everything. So if you wanted a button that did something, you sub-class the button. If you wanted a table that did something, you sub-classed the table and put your custom stuff in the sub-class. So when I first started with iOS development, I had a tendency to kind of use the same approach and try and create custom sub-classes of views. And then I eventually realized that I was kind of violating really all of the good practices and what I should have been doing instead is doing that customization by attaching the right delegates to those views so that when something happened in the view, that delegate could handle that thing happening, that event or that interaction, and then do something to the view maybe or to the set of views. Been trying to put that logic in the view itself, caused me no end of confusion and pain. JAIM: Yes, definitely. Keep things separate. PETE: There must be a place to do sub-classing. When you're actually building a view, like a presentation object or widget; you display it on the screen and you are using it in a lot of different places – I guess there is a case to bundle that into a sub-class. Maybe that the rule of thumb there is if you are actually customizing the user into the UI or customizing the look and feel, then that’s the case with sub-classing a view. But if you're customizing the behavior of that thing, then probably you wanna put that logic somewhere other than in a view sub-class. CHUCK: That’s one of the core principles of MVC, is having that separation of concerns. PETE: Yeah. CHUCK: And as long as you put things in the right place, then it really does kind of fall out neatly most of the time. PETE: So one of the things that used to really irk me about iOS was, there was a very rigid, kind of binding at one view controller to one screen in your UI. And that made it really tricky for me to take sections of that screen and have them controlled by separate view controllers. And when the first iPad came out, that was really, really hard because there's huge, relatively huge chunks of real estate and you kinda want to logically break up your screen into different areas that are controlled by different classes. But it was really hard to do that because there wasn’t really any way to have multiple view controllers interacting with the same kind of live on screen UI and then they added some stuff, I think in the first release after the initial iPad. The first iOS released after the initial iPad release that let you do – what do they call it? Like the subview controllers or something like that? Do you guys know these things I mean that you can control sections of the screen with the view controller? CHUCK: I've seen the concept, but I can’t remember what they're called, either. JAIM: Child view controllers? PETE: That’s probably it. That sounds like it, yeah. CHUCK: And it’s in that aspect that reminds me of MVVM. I mean, if you go look at, like, Knockout.js and things like that, they do that where you basically have a view controller or a view model that interacts with just one chunk of your overall view and then you can nest them so that you have larger context view models to handle, larger sections of page. PETE: Yeah. And it used to be really hard to do because there was this – so we have been talking about kind of the abstract ideas, but in the specifics, the view controllers in iOS, they're not really just responsible for receiving events from the views that they're managing – the hierarchy of the views that they're managing. They also respond to system-wide events or things like a screen rotation, right? And so, if that was really annoying when – if you wanted to have multiple view-controllers, how do you know which one is supposed to respond to the screen rotation? Should they each, independently, be responding to the screen location, moving their set of views around the screen? Or should they be waiting for some parent view controller, and then you have this kind of hierarchy of view controllers for each, like a parallel hierarchy of views or --. It got really confusing for a while before Apple kind of stepped in and created this kind of official way of managing that stuff. JAIM: Yeah, it made a lot clearer: have one view controller handling all of the stuff and everything else kind of feeds off that. PETE: Yeah, stuff like memory management was the same thing [inaudible] and once you do it, you get – yeah, anyway. I’ll stop. CHUCK: That’s all good stuff. PETE: I'm just reliving the pain of tearing my hair out, of trying to figure out how to get this iPad app to not be a huge ball of model with one view controller, while at the same time trying to learn the intricacies of the view life cycle with the view controllers and the views and all this kind of crazy stuff. Anyway, sorry. Jaim, you were saying something? JAIM: Let’s talk a little bit about how you actually implement MVC in iOS apps. Chuck talked a little bit about what the Model-View-Controller are – what does that actually mean when we’re actually building an application? So like the view has obviously your controls, your buttons, your layers, and your controller – your view talks to the controller through your outlets and actions. So that’s the communication that way. CHUCK: Yeah, you get to drag all the – it does the lines and drags all the stuff. Do they still call it ‘interface builder’? JAIM: I guess it is. I mean, it’s not a separate thing anymore but it’s still ‘interface builder’, yeah. We still call NIBs, NIBs, right? We’re never gonna give up that term. [Crosstalk] PETE: Oh, I've worked with someone that called them XIBs and it drove me insane. I kept on correcting him and he kept on not listening to me. CHUCK: I'm gonna start calling them XIBs now. [Chuckles] PETE: You heard it here first, people. I'm going to call them IBs – the ‘X’ is silent. JAIM: That’s right. CHUCK: [Chuckles] Yeah. JAIM: So how do we do the model controller communications? PETE: This is actually my question. Before answering that, it’s very clear what a view and a controller is in iOS world, right? A view is, it derives from UI view and – almost always derives from UI view – and is kind of generally loaded, defined in a NIB or programmatically, and then managed by a view controller, which almost always derives from a UI view controller. But the model, there isn’t really like – if you're using core data, then you're generally gonna be doing something that’s kinda based on core data. But the model, it can be any plain, old, Objective C+, right? There’s no kind of super class that it needs to derive from, or any kind of protocol that it needs to implement. CHUCK: Yeah, well furthermore, the persistence doesn’t matter. So, it could be core data, or it could just be some text file that you're writing to and from, or it could be a .plist, or it could be some service out on the web. JAIM: Yeah, the beauty is that the controller doesn’t care. Just talks to the model, and the model can do whatever it wants behind the scene. One thing I like talking with other developers about is like, “How do you design your models? Do you keep them kinda thin, like just kinda be your objects and this kinda data, and do your web services calls outside of that? Or do you keep a fat model where your model handles everything?” PETE: Oh, that’s a good one. JAIM: But, you know? It’s a kind of a thin, anemic model versus a really fat model. Or your model does so many different things --. But yeah, I'm always curious to see what would people do as kind of their default and what works well. CHUCK: What’s your default, Jaim? JAIM: I kinda keep a thinner model. I don’t do a lot of web service stuff actually inside the model, I think. I guess it depends. And I kinda go between different things based on what the app needs. I think, from the controller standpoint, I don’t do a lot of calling to web services or core data from the controller. The controller knows to deal with the model, but the model kinda delegates outside to, you know. If you're going to a web service, “Get this data.” And the model would go back, and when it gets it, it’ll call back to the controller, saying, “Hey, I got this data returned.” And since I keep a fatter model, but I do try and the model self-delegates to a number of different kind of web service stuff. That’s what I do. But yeah, I'm curious to see here what some people are doing. PETE: My rule of thumb with this stuff is, there's a couple of really good sources of wisdom on this as this concept of hexagonal architectures, which a guy called Alistair Cockburn defined a while ago. Then there's also this book called Domain-Driven Design that was written by this guy called Eric Evans. They're both really, really interesting, deep kind of concepts, but that concept with hexagonal architectures, also known as ports and adapters is –. One of the key principles is that your domain, like that core kind of thing that Chuck was talking about that represents your business logic and the core concepts of your application – so, users, and accounts, and line items, and things that aren’t really technical, but it more kind of reflects the reality of the domain, the problem domain that your app is working in. Those things should never know about the technical goop that they have to deal with to live in a real, you know, an actual application that’s on an iOS platform or a natural Rails application or whatever. So, if you keep that in mind, that’s a really good way to kind of answer these questions about how to think about it. So Jaim, your question, I really liked this question. Like, should my models go out to a web service to load themselves up? If you're sticking to the hexagonal architectures approach, the answer to that is “no,” because then your models, which are your domain would have to actually know about the concept of a web service, which they really shouldn’t if you are adhering to this model. So, one way of solving this –. So now you're kind of stuck with, “Well, I can’t do a web service call for my model” and “Why should I do it?” The way that I like to implement this, normally for any kind of less-than-trivial, or more than trivial-sized application, is to build repositories. So the idea of a repository in this one comes from this Domain-Driven Design book. The idea with these is it’s a kind of an abstract source of information about – it’s an abstract kind of source of domain object. So, you might have a user’s repository or invoice repository, and your controller – which is allowed to know about technical stuff because it’s not domain, it’s kind of the plumbing – your controller can go to a repository and say, “Give me the user with ID 55 or whatever.” And then that repository kind of encapsulates all of the talking to the web servers, technical stuff, and just creates domain objects. So, technical stuff – it’s allowed to know about how to create domain objects and how to interact with domain objects. Pure domain objects aren’t allowed to know about the technical stuff. So that’s kind of my rule of thumb for solving that stuff. CHUCK: Yeah, that makes sense. Yeah, going back to the DDD book by Evans, I wouldn’t suggest putting your network calls inside your model. Definitely, it’s – you know. For repository, I don’t generally call what I'm building a repository. But you know, if you go out to a web service using AFNetworking or something, that’s generally delegated from the model. PETE: Right. You do see that a lot web people will just throw their, their AF networking code into like a static method on – a class method on a model because it’s just like, “Oh, that seems like a good place to put it.” And it kind of is, to an extent, but I think really that’s muddying concerns because you're mixing in technical network-y stuff with that pure domain logic that should be all that your model knows about. This is also like if you're coming from the Rails world – models in the Rails world derive from active records. So models, by definition, in standard Rails, models by definition know about the database, which I think is actually a real kind of violation of this hexagonal architectures approach. They don’t have that concept of repositories and they end up always knowing – you end up always mixing together business logic and sequel, essentially. CHUCK: Okay. So does the hexagonal architecture – is that mentioned in Eric Evans’, or is that separate? PETE: It’s separate. The two kind of play together very nicely. I wouldn’t be surprised if Eric Evans references it. I think that hexagonal architecture’s concept has been around since the – I want to say mid-90s. So I think it’s an older – it has more kind of precedence than the domain-driven design stuff, but the two tend to interact very, very nicely. Almost all the DDD stuff helps with – all of those patterns kind of sit together quite nicely with these principles of ports and adapters, which is the hexagonal architecture thing. CHUCK: Okay, I’ll check it out. Yeah, I've got the DDD book. I’ve read the two chapters – same two chapters that everyone else read – ignored the rest. It’s massive and very dense. BEN: So, you have to read that book twice. It’s like that; that’s the thing. CHUCK: Ben! You’re here! BEN: I'm here, yeah. [Chuckles] PETE: It’s Ben Scheirman. BEN: I think I’ve read that book three times. PETE: [Inaudible] the second half is the better half, [inaudible]. BEN: You know what, I suppose that would probably be better. I think I read that book three times, and each time I just pick up something new from it. But yeah, this is one of my all-time favorites. PETE: So Jaim, you have a kind of question that you had rolled in earlier when you were talking about, “Should I do networking?” coz you were also kind of saying --. I think you were kind of implying like, “Should I have all my logic in the models? Or should I put my logic somewhere else?” And I think, again, following DDD or just following good OO, I think lumping everything into the model just because it has a name in the MVC triad is the wrong thing to do. So like repositories, for example – a really nice way of doing this stuff. But they're not an M, a V or a C, but that doesn’t mean that we don’t use them. And you can have the same idea for like, let’s say – tax calculation is always a really good, easy example for this. You could start off when you're doing tax calculation, just adding that into your invoice [inaudible] my invoice has some methods on it that help calculate tax for this invoice, and it goes through all of the line items and figures out whether it should have sales tax or not, and whether this one has an import duty and blah, blah, blah. If you feel like everything has to be an M, a V or a C, then you always end up putting this logic in an M, a V, or a C. But there's no reason you can’t pull that out into its own class. It’s its own thing. Tax calculation is its own thing and there's no reason that you can’t just create a plain old Objective-C class that represents the act of calculating taxes. And that’s what in – I think in Domain-Driven Design, he talks about that as service objects or service classes, something like that. To me, it’s a horribly overloaded term, unfortunately, but that’s the other kind of key thing that isn’t obvious when you first start building iOS; that was particularly because iOS apps are pretty small, but you don’t need to put everything in the model. You don’t need to put everything – you particularly don’t need to put everything in the controller. As the thing that everyone always ends up doing is the controller becomes the grab-bag of – it handles the geo-locations stuff and it also responds to networking things coming in, and then it also handles x, y, z, coz that’s what all of the sample codes does. Because all of their apple sample code things are tiny, little sample applications where you can get away with that. CHUCK: Yeah, I tend to lean more toward having the service objects, if I can. Mainly just because then the model can understand how the thing should behave and then the persistence or whatever you wanna call it is sort of incidental to that. So it knows when it’s supposed to save, but doesn’t really care how it’s supposed to save. PETE: Yeah. And this even extends as far as things like rendering tables. Almost everyone, particularly in iPhone apps, does what I do, which is you just may add all of those delegate methods onto your view controller where you just derive from UI table view controller and now your view controller, as well as everything else, is also managing the data for the table and deciding what [inaudible] and all that kind of stuff. That works fine if it’s a very simple case I suppose. But again, people get in the habit of doing that and then they think that that’s the only way that they can do it. But actually, Apple has really thought this through. When you create a table view, you don’t say, “This is the view controller, call this to get all of the information about what to display.” You give it an delegate. And you actually give it multiple delegates, right? You give it the data source delegate and you also give it the table view whatever-delegate. And those two delegates normally end up being the view controller because that’s convenient. There's no reason you can’t make a custom class whose sole responsibility is for basically controlling the rendering for that table view and being like a little mini controller that mediates between a set of data and a table view. And then your view controller – kind of the boss – all it does is kind of make sure that that table controller is set up correctly. It doesn’t actually do any of the – doesn’t implement any of the delegate protocols; it just kind of sets stuff up at the start of the day and then says, “Hey, you table controller! You know all about tables; I'm not going to get involved. This is clearly your responsibility. Here’s the table view, here’s the data; you guys get your stuff done. I'm just gonna focus on the very high level stuff, because that’s my role in this play that we’re playing out.” That make any sense? BEN: I'm actually a big fan of that sort of particular refactoring as they extract some complicated – well not really complicated, but related methods out of a view controller and into a distinct object. Admittedly, I don’t do that very often at all. I just end up sticking it in the view controller because there's no other possible pointer you could set on the delegate but itself. PETE: [Chuckles] BEN: The compiler [chuckles] will yell at you [inaudible]. PETE: Semantic error! BEN: Yeah. Actually, I just put all my code in the app delegate because that’s what Apple tells me. PETE: Yeah, right. That’s the worst of the worst violations. CHUCK: Junk drawer! BEN: So I have a problem with a lot of the sample – the Apple samples. And a lot of times is they're afterthoughts probably written by an intern. You got to take them with a grain of salt; it’s not like the official direction of Apple. Except when the new frameworks would come out of iOS 7, like the transition framework? There's a bunch of sort of things that need to stick around globally you that you can do like custom, interactive view controller transitions, and while I was digging into this, it seemed like the best approach – well actually the only sample code I could find stuck all that maintenance code in order to coordinate the transition in the app delegate. Of course you could just [inaudible] that onto another class or something, but it seems like their guidance, or lack of guidance and where to put that stuff just ends up making everybody on Stack Overflow suggest putting these things in the app delegate. CHUCK: So we talked a bit about how to organize our models and what our models are kind of responsible for. How do we do that communication between the models and the controller? Pete talked a little bit about the delegate pattern, which is kind of the default, where your view controller will be a delegate of the model. So when the model has to abate itself or signal that something has happened, just call its delegate, which lets the view controller to do its thing. That’s kind of the default, I think, for a lot of things. That’s what most this Apple code has done and Apple kinda leads us towards it, but there's some others ways to doing the model-controller communication. One thing would be notifications. Have you guys played with that? JAIM: Notifications are handy but they're also somewhat dangerous, I think, if you use them in the wrong way because there could be multiple listeners. I like the sort of more explicit nature of a real protocol with a real delegate, but there are times when you're too far removed from the situation, you just need to sort of passively listen for an event. In that case, I've used notifications but I don’t really use them that often. CHUCK: Okay. They’re useful if your model, if more than one thing relies on what's happening with the model, a notification could be pretty useful. With what Ben was saying –. BEN: With KVO. CHUCK: Yeah, that’s kind of the next thing. But you do have to be careful that you're releasing the notifications, and if you only care about the notification of a particular model and there might be different ones of the same type, that you're actually checking for that object. So there is more busy work and more ways to mess things up and cause weird bugs, because if something happens and you don’t [inaudible] and don’t release your notifications, you just kinda start getting multiple ones and you get weird things happening. So it’s definitely, yeah, I’d definitely go with the default as a [inaudible] thing, but occasionally, notifications can work. And also, like we’re saying, like KVO – KVO’s really cool. Because you have your model; the model doesn’t have to do anything. It has no concept what's happening outside of it; it just updates its property or calls method, [inaudible] to update a property. The model doesn’t care about anything outside of itself; it just kinda does its thing and everything else listens to it, which is pretty good. The thing that I have a problem with that, or I find annoying is that when you're listening, your KVO stuff all happens through one method. So if you're doing this on a bunch of different methods, then you have some massive IF loop. What's the name of that method? I can’t remember it. Data observe something – is that it? JAIM: Observe value for key path? CHUCK: Yeah, observe value for key path. Then you have – if it’s this type, if it’s this, if it’s this – so. BEN: We could probably do a whole episode on KVO, but maybe we should stop and do a definition. JAIM: I think that’s good. PETE: That’s twice. Two requests for definition in one podcast. This is awesome! CHUCK: I feel like I'm on the wrong show! PETE: Yeah, right. JAIM: Yeah, seriously. [Chuckles] Where’s Josh? CHUCK: So the running joke on Ruby Rogues is that Josh Susser always asks for the definition. That’s what we’re referring to for those who aren’t in the know. Anyway, go ahead. BEN: Okay, so KVO is Key Value Observing, and it’s a mechanism by which you can, say, I want to know as soon as this slider’s value property changes, because I need to change the actual volume of a hardware device. And by using KVO, you can get notified every time that property changes and typically, you would say “add observer for key path,” and you pass them the key path you want. In this case, it would be like in recorded string value, and then it will call the object that you just set up as an observer, call the method “observe value for key path.” And that is called for your class, for anything that you're observing, anything your super class is observing. It’s kind of a minefield; you have to get that implementation correct, because basically what you would do is you say, “If I'm interested in this particular value or key path, this is the one that I'm interested in, then I'm gonna handle it and I'm not gonna call super – because I handled it.” If I'm not handling it, then I should call super so that the super class doesn’t get muted from all of the notifications that it was depending on. JAIM: Yeah, it’s really painful. That ends up being like a gigantic switch statement. And then usually I’ll end up just grabbing all of the code for handling each specific case and pull that into another method. It’d be nice if we could just do that from the get-go and specify the selector that we want called. PETE: Someone must have written a little helper, open-source thing where you kind of – it does all of the observing and then you register blocks for specific key paths or something like that and it does all of the boring mechanics. JAIM: Yeah, that would be cool. BEN: That would be nice. PETE: Maybe a listener of this show can email us and let us know. I'm trying this out, see if this ever works. CHUCK: [Chuckles] PETE: I hear people doing it on podcasts all the time. CHUCK: Just start a git repo and start accepting poll requests before you write any code. PETE: I was considering it; all we need is a good name. I'm thinking – NSObserver. But that’s probably already taken, and also you're probably not supposed to use NS. JAIM: Another thing you need also to be careful with if you're doing KVO for your communications is to tear them down correctly, otherwise you get very strange side-effects. CHUCK: So do observers kinda fall into the view category, or the controller category, or --? PETE: That would be my question. So we’re talking about kinda using these for something, approximating data binding where the model changes and then the view updates. It doesn’t seem like you can bind these two directly together. You can’t bind the model – you can’t have a view directly do KVO on a model because then you’d --. Well, you could be, you'd have to sub-class the view and kind of that’s what we were talking about earlier as being not necessarily the right thing to do. So, I would assume – because I've never done this. I've thought about doing it but I've never actually done it. I would assume the way you would get this to work to do kind of data binding would be the controller observes, does KVO on the model, and then when the model changes the controller gets notified and then the controller, in turn, tells the view, “Hey, update yourself because the model just changed.” Is that correct? BEN: Yeah, if you look at the Cocoa way of doing things, the model notifies the controller or in this thing, the controller is listening for the model change, then it tells the view. So yeah, what you're saying is right on. PETE: Is this pattern more common in OSx? I feel like that’s where I see most people talking about OSx is – sorry, about KVO – I feel like I read that more in the OSx world than in UI kit world. Anyone know? BEN: We need to patch in Andrew for this. Where’s Andrew? PETE: Oh, yeah, yeah, right. Phone a friend. I'm just going to declare that to be true because it sounds legit to me. JAIM: I’ll back it. I’ll second that. [Chuckles] If two people said it, that’d be true. CHUCK: It’s always true until it’s not. Just keep that in mind. PETE: Idiots love company. CHUCK: [Chuckles] Alright. Well, are there any other aspects of MVC that we want to talk about? JAIM: Well one thing I've been playing with in some of my apps – and I really didn’t think of it as MVC, but if you start using more of like a block pattern, I mean, does that even makes sense as MVC where the model would kind of pass it on, you keep passing a block to the model like a controller, saying, “Okay, when this happens, just do this?” I'm not even sure you can call it MVC; I've done a little bit, but kinda doing more [inaudible] in this style of programming, seeing if that makes sense. I haven’t had a whole lot of success with it. I've been able to do it with small things, but for larger things, it’s [inaudible] quickly. PETE: Can you give a more explicit example of what you would be doing in that block or what would be happening? JAIM: Okay, so like in a model, if we’re using the delegate pattern, the model would have, “I did this. I updated this person.” So if you have a delegate method, delegate method just says, “I updated this person.” If you're doing a block, you could pass in a block to the model that’s defined outside of it with whatever you want to happen when the person is updated. So the model does its thing, says, “Oh, I updated data for this person.” It just calls the block method. So it’s more asynchronous, kind of JavaScript-type of way of looking at things, which – I never thought of it as MVC, but it could be considered as kind of a convoluted way of doing it. PETE: I've tried too the block-based thing with AFNetworking, and I preferred that to delegates. But I feel like if you did that in a controller, you would be kind of its deodorant for the fact that your controller is trying to do too much stuff. If you need your controller to have more than one or two delegates on it, then probably that’s the universe telling you that maybe your controller’s trying to do too many things and you should kinda be pulling that out into separate little helper classes. I get a little bit frustrated trying to do things with blocks because I think because I have happy experiences doing that in JavaScript land, and it’s really easy to just create anonymous functions and Objective-C is quite painful to do stuff with blocks. It’s better than not having blocks, but it’s still not as easy as in some other languages, so I always get quite frustrated trying to do something with blocks because it feels like it should be super easy and then I end up having to remember what stuff has to be retained [inaudible] and the under under block and all that stuff and I just get annoyed and throw my hands up in the air. JAIM: Yup, that’s pretty common. BEN: I do a pretty common example in this networking presentation that I've been giving. I take the new NSURL session block-based handler for an image download and then once I get it working, it’s kind of like download task with the URL and then it takes a block, one single block, which give you the URL of the downloaded file, whether or not there's an error in the task itself or the response. And then I say, “Okay, now I wanna show progress for this download.” And then unfortunately progress is not supported using that block-based form, so I have to sort of convert it back into the NSURL session delegates methods. What happens is interesting – you have, say, one block that is handling the call back for this request, and inside the block you need to do a bunch of things like disable the network activity indicator spinner and you need to check to see if there's an error in it. So you probably need to throw some sort of alert or you need to update the user interface in some way, which requires dispatching onto the main thread at the main queue. Then you check the response: if there's no error then you actually got a response so then you have to cast the URL response to an HTTP response to get the status code. Then you check that to see if it’s 200; if it’s not 200, again, you up your user interface for some sort of alert that has to be dispatched on the main queue and if you did get a 200, then you need to copy the file somewhere else. In my case I was doing it on a just to a UI image in memory, and then jump onto the main queue to set that onto the image view. So you can imagine what kind of an indentation nightmare that – three different IF branches, and there's a bunch of dispatching happening, and there's the disabling of the network activity indicator. All of those methods, all those things, sifted into like a much tinier method when done in the delegate variant. There's one callback that tells you when that request’s finished and that’s the place where you would get the error, and there's another one that tells you whether or not the file was downloaded, so all the file download transfer stuff goes there. It just cleaned everything up and put all those things into a distinct method, which is like your next refactoring trick in your pocket that you would take. You have this nasty-looking block method, now let me shift this into other methods. So, I don’t know. Blocks are awesome, but I think that sometimes they get overused. When there are too many parameters, sometimes it’s just nicer to already have those methods predefined and each thing has its place. JAIM: Yeah that sounds good. Just make everything explicit, clean – a little bit hard to test. PETE: Ciao. CHUCK: [Laughs] Any other tricks you guys wanna share before we wrap this up? This is good stuff. PETE: And I think the main thing that we’ve said in various different ways is that MVC is a really nice pattern and is really well-implemented in iOS, but it doesn’t mean everything has to be an M, a V or a C. The way that Apple have implements that makes it really easy if you separated that stuff out into more – in single things that are doing one, single response [inaudible]. And I think it’s very easy for us to get started by just throwing everything into the model or everything into the view controller, or force everything into the app delegate, but really, we should be dealing very [inaudible] to put stuff into small classes that do one thing well rather than grab a bag of [inaudible] one of them.  That’s my soap box. CHUCK: Well said. Awesome. Alright, well let’s go ahead and do the picks. Ben, do you wanna start us off? BEN: I actually have no picks today. CHUCK: Alright. Jaim, what are your picks? JAIM: So I'm out of picks too, but I'm going to make an anti-pick for Microsoft. Not in general, but their compiler, because I was talking to a guy about a month ago who’s an Apple developer. And kinda going back to what you were saying, Pete, about MFC – like, that’s what I did in the ‘90s; it was a weird time, I'm still kinda scarred from it. [Laughter] CHUCK: You make it sound like you did LSD in the ‘90s. JAIM: The ‘90s were crazy, man. You wouldn’t --. MFC was crazy. BEN: MFC made me hallucinate, too. JAIM: That’s how it went, man. But I'm talking to this guy, he’s like, he’s an Apple guy, so he has a Mac app and an iOS app and he wanted to kinda go to Windows and do a port. And he’s talking to me about his experience with it. He’s like, “I'm doing this thing called Microsoft foundation classes.” I'm like, “No! No, no, don’t do that!” But that was kind of like the default, because they’re, “Oh, C++! It’s still in there!” It’s still an easily-clickable option if you want C++ development and Microsoft Windows to do MFC. BEN: I'm probably not at all qualified anymore to talk about this stuff, but there was a long period of time where everyone is switching to .NET and there was WinForms. And WinForms, in my opinion, the limited amount of development I did on WinForms was painful and there were bugs that just never got fixed. And I know people were able to build apps with this but I had a really hard time with it. And then everybody started moving on to WPF, including Evernote. And Evernote eventually ditched their WPF code in favor of C++, and I wonder if they're using MFC, or if they're just doing their own – I don’t know, window management, I don’t know; I have no idea how that works. But if there's no alternative and MFC is still supported, I wonder if Evernote’s using MFC. CHUCK: I don’t know, I didn’t check that out. I need to put it into Windows; it’s been a while. JAIM: [Chuckles] Yeah, they complained that the WPF Evernote was too slow and that it uses the GPU when they didn’t need to, or something like that. They’ve kind of made a big sync in the Microsoft community about a large, high-profile app ditching the latest and greatest from Microsoft. BEN: I've got my afternoon reading set now, I'm good. JAIM: Cool, thanks! Okay, that was my one anti-pick. CHUCK: [Chuckles] Awesome. Alright Pete, what are your picks? PETE: My first pick – because we were talking about KVO briefly, even though we should do it, have a separate episode on that, but did a quick Google and it turns out the inimitable Matt Thompson has an [inaudible] installment about Key-Value Observing. I haven’t even read it, but I'm gonna pick it anyway because it’s Matt Thompson. I'm sure that’s got some gems and jewels buried inside of that page and it skips the .com/key-value observing; there will be a URL in the show notes. My second pick, I feel like I've picked this already, but I think I might have picked it on [inaudible] when I was a very special guest on the [inaudible]. Hexagonal ports and adapters – I already talked about this a bit, but I'm gonna add a link to the original article that Arthur Cockburn wrote. There's probably a better write-up somewhere else by now, because this is very old, but it’s kind of a canonical source for this, this idea of the domain not knowing about all the technical stuff, like separation of concerns. And then I'm going to pick something, which I'm not sure how I can link to it, but Saul Mora has a really good talk about some of this stuff. I don’t remember the name of it; maybe Ben will remember it because I think he was at the same talk that I was. But it’s about essentially design patterns – I'm pretty sure it was him doing a talk about design patterns in [inaudible]. BEN: In Amsterdam? PETE: Yeah. BEN: Yeah, that one you're talking about, if I remember correctly, it was at7 MDevCon last year in Amsterdam, and he gave a talk on design patterns. PETE: Okay. BEN: I’ll try and find a link for you. PETE: I’ll look for a link because I think that that conference, they’ve been posting the audio and the slides. They didn’t have video, but they have audio. He talked a lot about this idea of not bundling everything in the app delegate or the --. BEN: I've found a video recording of this talk, so I’ll post it in [inaudible]. PETE: Perfect. Thank you, my glamorous assistant, Ben Scheirman. [Chuckles] That’s all I've got. I haven’t got a beer pick this week; I've been slacking. CHUCK: If you’ve been slacking, you should have a beer picked, right? [Crosstalk] PETE: You know, that’s funny. I think of slacking as not drinking – I have my priorities [inaudible]. CHUCK: [Laughs] Awesome. Alright, well I’ll jump in with a couple of picks. First, I've been listening to a book series on Audible – it’s one of my favorite book series from when I was in high school. I was reading these – called the “Wheel of Time?” They do kinda get a little bit slow, and I haven’t read any of the [inaudible] ones, so, just to put that out there. Anyway, I've been listening to the New Spring, which is the prequel, and I'm really enjoying that, so I'm going to pick that. As far as code goes, I've just been buried with work, and so I don’t really have any picks. If you're a freelancer, though, I am going to be putting together a series of emails that you will get when you sign up for my goingrogue list. So if you go to goingroguevideo.com and sign up for the mailing list, then you will get the email with my video on how we went freelance and then you'll get a series of five emails that talks to you about how to raise your rate. And I'm working on a little, mini video course for that, and I'm working on a larger, fuller length video course on how to find clients. So, if you're interested in either of those, go check those out. And you can also go check out the Freelancer Show where we talk about this stuff every week, and that’s at freelancershow.com. Anyway, I picked me, I guess. BEN: Very nice. CHUCK: Picked fiction, and then picked me. And I'm just interesting fiction, I think. JAIM: Hey, OneNote, Evernote, was done with the Windows template library, which I'm not familiar with at all. PETE: Aaah. BEN: I don’t even know what that is. PETE: Oh, I remember the WTL. It was like they had the ATL, and then they had the WTL, and it was somewhat crazy --. BEN: Ah, I remember ATL. PETE: Yeah, it was like that crazy, C++ massive programming template stuff that blew your mind. [Inaudible] BEN: That’s interesting. CHUCK: You change one letter and you get WTF. PETE: That’s what I think of when I hear WPF. BEN: Yeah. What The Luck! [Chuckles] CHUCK: Of course, I'm a – I'm a Battlestar Galactica fan, so if you change one of the other letters to an FTL – so. Anyway, I digress. Well, let’s wrap up the show then. We’ll catch you all next week!

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.