045 iPhreaks Show - The Masonry Pod with Jonas Budelmann
The panelists talk to Jonas Budelmann about The Masonry Pod.
CHUCK: Everything is awesome! CHUCK: Hey everybody and welcome to episode 45 of the iPhreaks Show. This week on our panel we have Ben Scheirman. BEN: Hello, from Houston. CHUCK: Jaim Zuber. JAIM: I just spent all week removing all the [inaudible] from my code. I thought it was a good pattern or something. CHUCK: [Chuckles] I'm Charles Max Wood from DevChat.tv and this week we have a special guest and that is Jonas Budelmann. JONAS: Hello from New Zealand. CHUCK: So you wanna introduce yourself really quickly for the folks who don’t know who you are? JONAS: Yeah, I'm an iOS dev and I've been working on iPhone and iPad apps pretty much since the SDK came out and just love what I'm doing and have made a few GitHub projects. CHUCK: Cool. Are you the guy behind the Masonry Pod? JONAS: Yeah, that’s one of the projects I've released on GitHub. CHUCK: Cool, you wanna talk about that for a minute, just kind of explain? Ben brought up before the show that everybody loves auto layout. JONAS: Yeah, the auto layout on, I guess that’s one of those things that divides people because it’s such a different way of doing things and you can pull your hair out quite often when something goes wrong with it or it doesn’t quite work the way you want it to, so that’s good and bad, definitely, as its ups and downs. CHUCK: How is it so different from using something like Interface Builder? Or does Interface Builder now use auto layout? JONAS: I guess in XCode4, auto layout support for Interface Builder was quite rudimentary, let’s say. But now in XCode5, it’s a lot bigger, so you can do a lot of things and preview what your layout constraints will look like in different screen sizes and it would do a lot more for you to help you kind of solve issues that you have [inaudible]. Having said that, I predominantly use auto layout in code, which is a different approach again, which is why I created the Masonry. CHUCK: So, Masonry just makes it prettier? Is it just a nicer API on top of auto layout, or is there more to it than that? JONAS: Yeah, that’s pretty much the gist of it. So I guess Apple has to provide a sort of very basic framework, and then I think it’s up to the [inaudible] developers to put nice APIs around at the very low-level, generic APIs that Apple provides, so things like AFNetworking – while they enhance a lot of what Apple is doing, a lot of that is just providing nicer APIs and addressing more the common use case. JAIM: So I tried creating using auto layout with XCode4 and code, and I ended up running away screaming from the pain. [Inaudible] it’s gotten better; can you tell us what the difference is between doing kind of a – walk us through what it’s like creating layouts, auto layouts in code and tell us how you kinda make sure it does things better? JONAS: Yeah, I guess you have two options when you create auto layout in code. One of them is the most low-level API which NSLayoutConstraint and you create a constraint with item, and you have to ask all the different things you need for that constraint. So this method actually has seven parameters to it, so that quickly becomes unreadable. For one constraint, you need to call [inaudible] seven different parameters that you only need to two of those, imagine it, it becomes quite verbose. The other option is to use Visual Format Language, which is an SK-type string which you pass in which represents your auto layout constraint that you wanna create. It’s a bit more visual, but some people find that quite hard to understand yet to translate all your views and give them names and [inaudible] as well. And it also returns you an array of constraints, so if you later want to remove just one of those constraints or animate just one of them, you have to sort through that array and it’s quite hard to determine which constraint relates to which part of that SK-string that you passed in. BEN: I think the auto layout Visual Format Language is definitely preferable than just creating the sort of the object model from scratch, because it’s way verbose. If you imagine all the things you need to specify when dragging a line from one view to the edge and specifying that it’s a horizontal spacing constraint or whatever, doing that in code is quite wordy. I think the Visual Format Language is pretty nice once you understand it, but I think the problem is it’s not discoverable at all. In fact, I know a lot of people don’t even know about it. JONAS: Yes. BEN: So, given that, you can do a lot with the Visual Format Language. What made you sort of still want more flexibility and expressiveness with some tool, which ended up being Masonry? JONAS: There's a couple of reasons – one, because I'm doing all my layout in code and all the view I don’t use in spaceCoder. That means I wanna do all the animations using auto layout, and doing that with Visual Format Language is quite hard. And I also prefer not to use kind of a string-based method for lining up, for creating my constraints. JAIM: So how does Masonry make this better? JONAS: Masonry uses the kind of object model way of creating your constraint, but it reads like a sentence. So for example, the syntax for creating a constraint relating lift to the right of another view you'd say, make.lift.equal.to.other.view.right so if you come back to that in a few months, you can rate it and understand what that constraint is doing. Whereas if you come back tone of the other low-level APIs it’s quite hard to get your mind around what that constraint is creating and what that’s actually doing, so it’s a bit easier, I think, to read, which definitely increases getting you ahead around the constraints and understanding what they're doing. BEN: Okay, it sounds like this is a sort of fluent interface for doing the constraints, is that correct? JONAS: Yeah, that’s a good way of describing it, yup. JAIM: I guess that definitely helps with making it discoverable for other people just to see what you get to chain things together to see what operations are even available. JONAS: Yeah, definitely. So I guess I also get to see the option of if you don’t need the multiplier or the constant attributes of a constraint, you could leave them out. So it’s only what you need and nothing more, kind of thing. JAIM: It’s very cool, I'm looking on the GitHub page and it has an example. You're passing a constraint, the code actually reads out pretty clean, make.top.equal.To whatever top would offset. So I think that’s a very simple way of explaining what you're trying to do and making it very readable. Yeah, I can agree. I can see why this could be valuable. JONAS: Yeah, I guess, definitely readability was my main goal with creating Masonry. Just to make it easier for someone else to look at the constraints I'm creating or to look at someone else’s constraints. I can pretty much understand them, just read them out and get my head around them pretty quick. CHUCK: Do you have any apps out there that you're using this with? JONAS: I'm currently working on a project at the moment, but it’s under NDA that’s using auto layout through Masonry. CHUCK: Oh, very nice. I love those. I'm working on it, I can’t tell you. JONAS: [Chuckles] JAIM: It’s so amazing, your mind will be blown. Does Masonry expose anything that’s not on Interface Builder that are not easy to do? JONAS: I guess it has a few composite constraints, which basically lets you create multiple at once. Say, if you want to make all the edges equal to a certain view, match it exactly, you can do it kinda using one line of code rather than creating four constraints for left, right, bottom and top, which is quite handy in terms of counting down and also just increasing that readability, again. CHUCK: Were there any design decisions that were hard for you to make, or was this mostly pretty straightforward as far as how you wanted it to come out? JONAS: Yeah, I guess one of the – I guess most of my design decisions was it’s kind of breaking convention in terms of the way this is the dot notation. That almost doesn’t look like objective-C because you're using round brackets and as you guys would know know, when you're writing objective-C, when you're calling methods and stuff you use square brackets. The reason then for that is if you're using square brackets, basically you'd have to name all the method parameters that you're going to call, so you're losing the benefit of chainability. BEN: I think you’ve alienated every long-time Mac developer. You’ve got dot notation, you’ve got auto layout, and you got Cocoa Pods, I think. They already left the show. [Laughter] If Andrew was here, I don’t know what would have happened. CHUCK: Can you write this with the square bracket notation, or is there a reason why you shouldn’t? JAIM: Well I think you would have a square bracket explosion on the left hand side so that every time you wanna chain one, you got to add another wrapping. If you're like a list fan, maybe you don’t care. It just really, really hurts the readability when you do that. I do like how, even though this isn’t necessarily objective-C style, it is isolated to a block, which yields like a builder object, and so you really don’t need –. I also have to applaud your use of prefixes for the categories. You start of making constraints with the specific view and that is when I make constraints method call, but that one has to be prefixed with your MAS prefix, so it doesn’t collide with potentially anything else that does similar things. But then once you're inside of that block, the majority of these function calls come from MASConstraintMaker, which since they all yield the same object, I guess every operation still returns to the builder so you can chain them together then you end up having an easy way to –. This is definitely familiar to Java developers, because there's a lot of APIs like this in Java. And .NET had similar, I would say, there are lots of libraries out there that do similar things in a fluent way, some of them being ports of Java code. But I don’t know how familiar this to objective-C developers, because this is inherently sort of cumbersome with square brackets and texts. So even though it’s different, it is isolated to the one block, so it’s kind of like, “Oh, okay. I'm in like this new mode where I'm going to chain together some things.” And you compare these two lines of code in your example with the 30 lines of code of how to do it with just NSLayoutConstraint. You know, “I’ll take the shorter one, please.” [Chuckles] JONAS: I guess going to your point about you using, you're creating these constraints within that block, it also helps because you know that all those constraints are related to one view when you're creating it through Visual Format Language or a low-level syntax. It becomes hard to tell which constraints relate to which view, so that also improves the readability. BEN: I noticed that when you're sort of storing a reference to these constraints, these are your own constraint class instead of NSLayoutConstraint? Is that a sub-class of NSLayoutConstraint? How is that different? JONAS: No, it’s using composition instead of inheritance, so the actual constraint is contained within that object as a property, and that allows us – because at any point within that chain you could save off that reference, so it always has to, it needs to wrap that NSLayoutConstraint rather than inherent from it. BEN: Okay. So then if you wanna do things like – WWDC Apple showed off an example where you have this nice auto layout-driven interface, but then there's this new view that comes into place somewhere and you need to be able to reshuffle your interface based on this new element that you're adding in and so they showed off the ability to create a constraint and animate it, so that you could say, ‘make room for the new instance’ and you can even make outlets for your NSLayoutConstraints. Can you do the same thing with this system? I suppose you wouldn’t be using Interface Builder quite so much, but I'm just wondering about animating constraints or dynamically adjusting the constraints after you’ve created them. JONAS: Yeah, so thhe main thing that you can change on a constraint is called the constant, [inaudible], so that’s quite easy to change with Masonry. And I guess the other thing you wanna do when you animate is uninstall a constraint and add a new one, so those things have been taken care of and you can do those things while you're animating. JAIM: So if you're writing our constraints in code, what is debugging like? Are you just basically firing up the simulator and checking to see if everything lays out the way you expected? JONAS: Yeah, and often you come across kind of the outputs and the console, which will tell you you’ve got too many constraints or not enough constraints. And one of the things that Masonry will help you with in debugging is you can assign a name to each of your views, and so instead of getting memory reference, so I’d tell you UILabel 0x37ny, you can say that’s the message label that’s the header view, so you can give names to those constraints and they’ll come out in the console debugging messages. For example, one of them tells you you're unable to simultaneously set up constraints and it’ll give you nice names for your different views, rather than numeric references. JAIM: Oh, it’s very cool. Is there any custom error reporting from Masonry or is it all the stock, built-in stuff? JONAS: Yeah, it’s that all using custom-debugging names for each constraint, so it uses the built-in Apple error reporting when Apple goes ‘give me the debug message for this particular constraint.’ Masonry overrides that and provides a new message with names and you can name the constraints and also the views to give you a bit more of an idea of what's going wrong and where it’s going wrong. JAIM: Oh, very cool. So what has the usage then? I noticed that the GitHub repository has quite a number of stars and forks. Have you heard of this being used in any sort of major applications? What is the general response from the community been? JONAS: Yeah, it’s been really good. I was quite surprised that it seems to be used by a number of apps and also just the fact that the syntax is maybe breaking a little with convention but people seem to have taken it up really well. I've gotten a lot of tweets saying it’s helped them understand auto layout or made an auto layout easier for them, so that’s quite encouraging, and it’s been great to get more requests and contributions from the community, so that’s always nice to know people are using it and want to improve and help develop it [inaudible]. Yeah, it’s been great. BEN: I noticed that – I mentioned applauding your use of the prefix for category methods because there's quite a few category methods that it adds to views. Then I noticed in the documentation that you have the shorthand defined, so that if you want to run with scissors or if you wanna live on the wild side I guess you could turn that off. Could you talk about how that mechanic is pulled off? Because it depends on define being set somewhere in where it could pile time, right? JONAS: Yes, by default the shorthand is off. When you turn it on, you can still use the prefix version, but all the prefix versions will, when you call the unprefixed version, all just forward that message on, and that’s just done and so they get a – if you define that shorthand then when it goes and imports all the Masonry files, it will switch on those using if-if statement. BEN: And you're using like NSforwardInvocation or is there some meta programming at work here? JONAS: It’s much more manual than that, yeah. A macro to afford all those different methods on. BEN: Yeah. I think it’s technically very cool and it’s good for the people who really can’t stand the prefixes but I would still recommend just to live with the prefixes. It’s safer, especially since the attribute names that you have for all of your view attributes – left, top, right, bottom, leading, trailing, width, height, center x, center y baseline – any one of those could easily be something that Apple decides to define later on, and theirs might just be afloat. JAIM: You should create a new pod, make it really popular and just throw in stuff in there, [inaudible]. [Chuckling] BEN: You mean like 320? CHUCK: You call it a framework. BEN: Yeah, I think it’s becoming more widely-accepted, but there are so many pods out there that I like. “Ah, this is a cool idea, but I'm probably never going to use it because they didn’t prefix their methods.” There's a good NSHipster – well, I’ll save it for the picks then. [Chuckling] CHUCK: Awesome. Do you guys have any other questions or thoughts? BEN: I'm kinda out of questions. This looks like pretty straightforward auto layout code, just a lot easier to read and write, so I'm looking forward to trying this out in an app to see –. I'm also embaffled by auto layout a lot of times and sometimes I will rage click that checkbox in Interface Builder to turn it off because it’s doing something that I don’t understand and sometimes you just need to get things done. The old way with auto layout turned on with springs and struts is so much of an easier model to understand and there's definitely cases where you have to write code to handle, ‘oh, this label now needs to be larger because – or smaller, depending on the language or whatever’ but in lots of cases I enjoy writing the script system of equations that you'd get by manually setting frames. And as long as you use descriptive variable names and constants, it’s really also pretty expressive. So I'm still not just – I don’t dislike the manual layout of views in code, but certainly if I'm using auto layout I will definitely look at something like this to make my life a little bit easier. JAIM: Yeah, with the rumored kinda larger screens coming I think this Fall or whenever they're coming, I think auto layout becomes a little bit more usable. BEN: Yeah, it was kind of funny. Apple had the iPhone4 and 4s and around that time they said, “Hey, an auto layout and *wink wink* you should be using it *wink wink*.” And then the next year, at WWDC, they're like, “Okay, and the iPhone5 – by the way, we told you last year that you should be using auto layout, so had you listened to it your app it would probably be laid out correctly.” JONAS: I think also the variable tech sizes helps a lot with the, say, if the user sits there, takes [inaudible] more like your interface can adapt easier if it’s constraint-based. BEN: Yeah, and if you're localizing to German then you need to add like 40 characters to every word and see how your app lays out. CHUCK: So are there instances where you would want to use this regular auto layout instead of the Masonry pod, or does this solve all the problems for all the people? JONAS: I guess the project that I've been working on, I'm coming across the need to use, to drop down to kind of the more low-level Apple frameworks, so I think you can, if you adopt it it’s better to stick to one method rather than mix all the different options within one code base. You’ve got some consistency, so if you're going to go with one way, you might as well kinda stick with it and go with it. CHUCK: Yeah, makes sense. Are there any features that you're looking at adding to Masonry, or is it pretty well-done until Apple updates the underlying structure that you're built on? JONAS: I'm always kinda open to any features that the community throws out there in terms of if they need more convenient sort of I have an idea of how it could be easier to use or how it could build on auto layout a bit more but at the moment I think that’s covering pretty much all of what you can do with the low-level framework but in a more readable way, so I think it’s built out quite a bit. So until Apple adds more features and we need to get parity with that and support those features in Masonry, I don’t think there's too much to do on it. JAIM: Yeah, one thing I like about this is you’ve got properties for the different priorities. They're set by the system, which are kinda hard to find to in Interface Builder. I end up just throwing in numbers; I had to create my own random scheme and ended up forgetting what my different priorities are. But I like the priority high, priority medium, priority low; I've seen this chain on your constraints, so I think that’s pretty cool. JONAS: Yeah, that thing as well, what you said earlier about using constants definitely helps a lot as well if you define all your padding as a constant and then you can pass it into Masonry. You can change it on one place and that’s one of the benefits of doing it in code – you can state one variable and then all your layout will change depending on if you change that padding from 20 to 40. JAIM: Yeah, definitely. I've spent a couple of days this week trying to get pixel-perfect images to line up correctly and yeah you do a lot of setting your variable, setting your floats for your offsets, how much past the actual image does this image go with transparent [inaudible]. So setting constants, very helpful. BEN: It’s definitely helpful, and it’s wordy and tedious or whatever, but I mean, at that moment you're burying your head in the problem of laying out your views, which I think is a plus. When you're just sort of clicking and dragging around lines, perhaps your brain isn’t quite so engaged in exactly what you need for that layout. So I think that the deliberate hand coding is, I don’t know, can be thought of as a benefit. The other thing I really like about doing it in code is that you can diff it really easily, so if you accidentally fat-finger something, you don’t have a merge error that happens in a storyboard, which you probably never find, right? JONAS: Yeah. BEN: Those are the types of things which, like you would be able to diff two versions of a file and say, “Oh, this is why the layout is messed up, because I accidentally set this to 25 instead of 30 or whatever.” So I don’t know, there are definitely downsides to doing it in Interface Builder, however, this certainly demos well. If you know what you want, you can certainly click and drag faster than you can type them up. JONAS: Yeah, I guess you can mix Interface Builder with Masonry as well, so if you wanna lay everything out in Interface Builder and then later you could use Masonry just to add those constraints that maybe you need to do programmatically or if you're inserting a view depending on a button click, you can do that using Masonry and keep your main layout in Interface Builder. CHUCK: Awesome. Are there any more questions and comments, or should we get to the picks? BEN: I think we’re ready. JAIM: I'm good; I'm ready to auto layout. [Chuckling] CHUCK: Alright, cool. Well Jaim, what are your picks? JAIM: So I have two picks today. One, we talked about Masonry being kind of a instant [inaudible] builder pattern. There's a blog post from two or three years back that helped me kinda understand how to do a builder type thing in objective-C. so if you're listening to our podcast and wondering, “What are they talking about this fluent in builder-type stuff?” I've found a good blog post that kind of explains it pretty simply. It’s called the Builder Pattern in Objective-C. It’s by Eric Dörnenburg, which I probably misspoke. My second pick is a whiskey pick. For my birthday a week or so ago, my dad gave me a bottle of Russell’s Reserve Bourbon, which is very fantastic. Not terribly expensive, but maybe a little bit more than your average bourbon. It’s one of the wild turkey ones, which I haven't really done that much of. I kind of stick to the Jim Beam; I drink a lot of Knob Creek. But Russell’s Reserve – very good. It’s kind of a rye forward bourbon, so there's good rye in there, good rye spice, but a lot of the stuff that you like in a good bourbon, so I definitely recommend. Check out Russell’s Reserve. Those are my picks. CHUCK: Alright. Ben, what are your picks? BEN: Okay, so I eluded to my NSHipster pick earlier on name spacing and I think it’s just required reading for objective-C developers especially library authors. I mean, we’re building software that will end up in somebody’s pocket and possibly never touch for many years, and software moves fast, so it’s important to –. Because objective-C lacks name spaces, it’s important to use prefixes where you might collide in global scope. And that’s where all our handy dandy prefixes go or come from. Anyway, go read that article and practice safe objective-C library development. The next one is a movie pick. I recently re-watched True Grit. I did see it in theaters and I just watched it again; that’s just such a fantastic movie, I really like it. It’s full of quotes too, I was like quoting it on twitter repeatedly, while watching it. The next pick is a, it’s like a static site generator, but it’s more for non-programmers, I would say, called Cactus for Mac. It makes it easy to create a single-page portfolio or gallery or blog and Cactus is, I believe it was designed by some of the people who used to work at Sofa, which is kind of like a famous development company that got sort of absorbed by Facebook, and now those guys they’ve done their two years or whatever, and now they're off working on cool, new things. Anyway, I like – just the overall experience is really good. I don’t have a site in mind for doing this, but the next static site I need to build I’ll probably try it out using Cactus. And then last one, I will also do a whiskey pick. I'm not really a bourbon connoisseur; I like scotch. So a friend of mine recommended Noah’s Mill bourbon, and I found it in my local [inaudible] liquor store, and it is super good. I made some old fashions with it. The only problem is it’s like 5000 proof bourbon – it’s really, really potent. I don’t know the actual proof, but anyway, it’ll sneak up on you, but good for old fashions. So, those are my picks. CHUCK: Awesome. I've got a bunch of picks. Last week, my wife and I went to the Saint George Area Parade of Homes, which was, it was a lot of fun. Saint George is a city in southern Utah; it’s about a couple of hours from Las Vegas. Anyway, it was fun, we saw a bunch of houses, we get ideas for things that we would like in our house, so. Anyway, I really enjoy going every year with her, and we usually wind up going around her birthday – her birthday was on Sunday, so terrific and a lot of fun. I was also doing some work for a client; we’re building an application he’s about to launch, and he was looking for a theme, and we had built everything on twitter bootstrap version 3 and we were looking for an admin theme for him, and I found one on startbootstrap.com, and so I'm gonna put a link to that in the show notes as well. And finally, I've been reading a couple of books. They're really short books and I'm almost halfway through Running Lean by Ash Maurya, and he kinda takes the Lean startup ideas and gives you a little bit more practical advice on them. I recommend reading the Lean Startup book first, so you get a really god idea of what it’s about, and then go read Running Lean. The other book I read was Tribes by Seth Godin. I'd read it before, but every time I read it I'm kind of inspired to be a little bit more of a rebel. Anyway, those are my picks. Let’s hear some picks from Jonas. JONAS: My first pick is the Mantle framework by iOS and Mac. So if you're doing a lot of API calls in your application and you need to pass all your adjacent models into objective-C, this is really handy and lets you do that in a more structured, clean way. And my other picks are – I just recently got a new Mac book because my previous one decided to blop on me, and while you're doing that, I guess you explore different apps and maybe you refresh some that you haven't used in a while and you look at other options. So instead of going for the Photoshop and NSTrader, this time around I've gone for Pixelmator and Sketch, which I found very cool. Maybe a little bit more lightweight than NSTrader and Photoshop; you can’t do 100% of the things you can do, but I'm not a designer, I just need to crop a few things or resize a few things or save to a different format, so for that and a little bit of very basic image touching, those have pretty much fulfilled my needs at a fraction of the costs. That’s definitely worth checking out if you need to do basic image editing on Mac. CHUCK: Awesome. We’ll be doing a Book Club book. BEN: Functional Reactive Programming by Ash Furrow. CHUCK: And we’ll put a link to that in the show notes as well and remind you to start reading it so that we can talk about it here in a few weeks. I guess other than that, thanks for coming, Jonas. JONAS: Thank you for having me. CHUCK: Alright, well we’ll catch you all next week.