JAIM:
It’s by you [inaudible], Chuck.
CHUCK:
Nope. Yeah, I can count with my shoes on.
[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York and L.A. bid on iOS developers, providing them with salary and equity upfront. The average iOS developer gets an average of 5-15 introductory offers and an average salary offer of $130,000/year. Users can either accept an offer and go right into interviewing with a company or deny them without any continuing obligations. It’s totally free for users, and when you're hired they also give you a $2,000 signing bonus as a thank you for using them. But if you use the iPhreaks link, you’ll get a $4,000 bonus onset. Finally, if you're not looking for a job but know someone who is, you can refer them on Hired and get a $1,337 bonus as thanks after the job. Go sign up at Hired.com/iphreaks]
CHUCK:
Hey everybody and welcome to episode 139 of the iPhreaks Show. This week on our panel, we have Jaim Zuber.
JAIM:
Hello!
CHUCK:
Andrew Madsen.
ANDREW:
Hi, from Salt Lake City.
CHUCK:
I’m Charles Max Wood from Devchat.tv. A quick shout-out for Freelance Remote Conf coming up in February, and iOS Remote Conf coming up in April. So if you're looking for some conferences, you’re going to have to drop the big bucks to travel to, then those are options.
We also have a special guest this week and that’s Josh Brown.
JOSH:
Hello, from Indianapolis.
CHUCK:
We brought you on today to talk about parsing JSON in Swift. Do you want to give a brief intro and then talk briefly about that and the book and what’s going on there?
JOSH:
Sure. Parsing JSON in Swift is not as easy as it should be. I learned this the hard way by doing it. I found out Swift is a great language and it’s easy to use and learn and Apple claims that these things. But then parsing JSON is not so simple, it’s not so easy and it’s not so intuitive. I think the main issue here is that Swift is really strict about types and nil and JSON is not.
I’ve written a few articles but I wanted to write a book to help people get past these stumbling blocks that Swift seems to put in your way when you're trying to parse JSON.
CHUCK:
Makes sense to me. Nobody – and by nobody, I mean everybody is using JSON.
JOSH:
Yeah. Exactly.
ANDREW:
So you’ve written a whole book about this and if somebody came up to me and said, “I’m going to write a whole book about parsing JSON in Swift,” I’d say, “There’s really enough there to write a whole book about.” To do this, go through – and actually I know. Having [inaudible] to this problem myself, basically everybody’s trying to do it in Swift. I know but could you explain why this really is actually kind of a tricky problem in Swift?
JOSH:
Yeah. Like I touched on before, Swift is really strict about types and nil and thing like that. It wants you to know beforehand if a type is going to be nil or not. It wants to know exactly what the type is, if it’s a string or an enter – whatever.
With JSON, you don’t always know that. A lot of times in JSON, you may not get a value for a
certain property or a property may be missing in the response and that’s totally okay with JSON, but it’s not okay with Swift. So you have to account for that in Swift and that’s where it starts to get tricky.
I’ve seen a lot of code – written some code myself that is expecting a certain type and then suddenly it crashed. I’m expecting an integer and because of the way I wrote the code in Swift, bam, the app crashed. Those are the sorts of things that I want to try to – that I do tackle in the book; hoe to cast from one type to another, how to handle nil and missing data in the JSON.
Things like that.
JAIM:
So what are the basic approaches you can take for handling the [inaudible] approach from JSON to Swift?
JOSH:
There are a couple of different things. One, you can use the built-in NSJSONSerialization. What that does is it takes your JSON and turns it into dictionaries and the basic Swift types, so maybe arrays, strings and things like that. Then there are a whole bunch of third party frameworks out there that are designed to make it easier to do JSON parsing in Swift. Because usually, using NSJSONSerialization gets you part of the way there, gets you to the dictionaries and things like that. But usually, you want to have specific types like model objects that make it easier to program against and the rest of your code. Those frameworks out there are designed to help with that.
JAIM:
Okay. So the basic barebones approach through just coding it’s – we’ve got your
NSJSONSerialization that gives you a dictionary of a very discrete values out of it. [Crosstalk]
JOSH:
Right. Yes, exactly.
JAIM:
That gets tedious pretty quick.
JOSH:
Yes it does.
JAIM:
So you’re saying if something’s not like you expect it, like it’s a string but it’s actually an [inaudible], you get crashes?
JOSH:
You can. If you code it the right way, you can prevent those crashes. Sometimes, people will try to – the term is called forcecast or force unwrapping object. If you try to force something to an integer that’s actually a string, then yeah, it’s going to crash.
You can cast a different way like use the safe typecast operator, and if you do it that way, then your code doesn’t crash but then you have to deal with the optional value that you get back.
JAIM:
Okay. So the forcecast, that’s your exclamation point. That’s the bang, right?
JOSH:
Right. Exactly.
JAIM:
Users, listeners – don’t ever use that.
JOSH:
Right. [Chuckles] Yes, please don’t.
JAIM:
One takeaway from this podcast. If you're still using that, don’t.
JOSH:
Right. Yeah.
JAIM:
But there are other approaches so you do an optional. I start this field to be a string, some type, or a string that I can convert to this model and you do the optional cast. It works great; what do you do if it doesn’t work.
JOSH:
Yeah, this is one of the things that is in the book as well. Basically, it depends on whether that property you're trying to get from JSON is critical to creating, say, the model object. Or is it just a thing that would be nice to have.
For example, we use the GitHub API in the book to parse repositories from the GitHub – from GitHub. So if I’m listing repositories, it’s pretty important to me to get, for example, the name of the repository. So I write code that checks to see – to make sure we got the name and if so, we can create this repository model object. We can create an instance of it and work with it.
If the name is missing, then it returns nil and then just nothing is displayed for that repository.
Versus, for example, in the sample project, it also shows how to parse things that are less important like, for example, a homepage. Maybe a project has a homepage somewhere else on the web, and if we get that then great, we can display a link to that homepage so the user can tap it and go see the homepage. But if we don’t, then it’s okay; we can just not display that. That’s how we handle it.
So basically, if it’s required, then go ahead. Check for it and then create the object, and if it’s optional, then do a check. But if it’s not there, that’s okay.
JAIM:
Okay. This typically maps down to how you're actually defining your models [crosstalk]. A field could be optional or [crosstalk] could be strict type. Like if it’s a user, maybe you’ll need an ID, maybe you don’t need a pet’s name or something like that. I don’t know.
JOSH:
Right. Exactly.
JAIM:
That’s the brute force approach which I’ve tried doing and it was pretty painful. I went looking for a library pretty quickly. What are some of the libraries that people are using for parsing JSON?
JOSH:
The most popular one is SwiftyJSON. I actually – in the book and most of the time when I’m writing JSON parsing code in Swift, I don’t use a third party library. I’m okay with NSJSONSerialization and transforming those into objects.
I think frameworks like SwiftyJSON are really helpful when – maybe when you get an array of data that isn’t – that doesn’t necessarily need to be an array. There’s only one object in it. It’s a lot easier to use SwiftyJSON to traverse the whole JSON structure and grab the value you want.
But like I said, in most cases, I found that NSJSONSerialization is great. It does what I need it to and something a framework like SwiftyJSON, doesn’t buy me a whole lot for the cost of adding yet another third party framework to my app.
JAIM:
Okay. So you're proposing a roll your own mappers.
JOSH:
Right. Basically. Yup.
ANDREW:
So one issue that you’ve touched on is that if you're writing JSON parsing code in Swift, it’s really easy to get it wrong in such a way that it will actually crash with bad data, particularly if you're using – it’s even worse if you're using forced unwrapping or forced casting.
But anyway, how can you – you don’t want to ship an app or you're kind of like, “Well, I don’t know. If the data from the server changes, this thing might start crashing.”
JOSH:
Right.
ANDREW:
So what are strategies to minimize that so you can say with confidence that even if I get bad data,
at least my app’s going to do something reasonable with it.
JOSH:
Right. One big thing is to actually write unit tests for the code and to make sure that if you send bad data into your JSON parser that your JSON parser can handle it, return something reasonable without crashing.
The other thing that we already touched on was not using forced unwrapping but instead using the optional unwrapping so that you're not causing it to crash.
ANDREW:
You actually spend a fair amount of time in the book talking about until testing and how to write tests for your JSON parsing code. And actually, I think you did a good job of just really – it’s not even JSON parsing-specific but it’s a pretty good overview of how to do testing, specifically in Xcode. But I’m curious what your motivation for spending so much time on that – in the book [inaudible] is?
JOSH:
To me, the problem that that solves is that I got unexpected data from the JSON backend and my app crashed. To me, writing test helps me to prevent that from happening. So if I write tests and the test pass and they don’t crash, and if I’ve tested thoroughly with bad data and unexpected data and things like that, then I feel a lot more confident in my app.
I am a big believer in unit testing in general, but specifically for JSON parsing, I think it’s important because you can get data that you don’t expect.
JAIM:
I’m going to give a plus one for that. I’ve been working on a Swift app for over a year and we did JSON parsing testing from the beginning and it’s saved our tail so many times. It’s definitely worth it, this [inaudible] the code.
I have a question on how do you set up your test? Are you having an actual JSON file and putting it into the test project? Are you mocking up dictionaries? What approaches do you take?
ANDREW:
Yeah. The approach that I normally take is to create JSON files inside of the project and then load those into tests then send that data into the JSON parser.
I like this approach because it’s easy to update so if for example, the API suddenly – we’ve added a new property to it and we want to parse that in the app, we’re going to test that as well.
It’s easy to grab a response from the API with Curl or with some other tool then drop that JSON right into the test file to update that file. That’s the approach that I like; it works really well for me.
But using dictionaries makes sense, too, in some cases.
JAIM:
It’s an interesting point to do actual live data using Curl. We were [inaudible] to do that but that’s a good approach. We generally just wrote our JSON files by hand based on what we needed. Eventually up to the point where these files were so big and we had more weird cases we want to test and we went to the approach where we’re started to mock up the dictionaries just so we can test all the cases without having all these files sitting around.
It helps at one point when you want to get more granular, but we definitely started having actual JSON files in the project and [inaudible] you up which test it which is very reliable.
JOSH:
Yeah, absolutely. That’s the other – the other thing I like about it is that it does test end to end. It exercises the NSJSONSerialization or whatever third party framework as well as how your code handles the output from that if you’re converting it into model objects and thing like that.
JAIM:
Okay. Now, I use SwiftyJSON; I’ve been pretty happy with it and there hasn’t been a flux in JSON handling APIs to really refactor and make it work against me. Are there other libraries people are using and liking?
JOSH:
That’s a good question. I think there are a few other libraries out there that are popular. I know that SwiftyJSON is the number two most popular Swift repository in GitHub next to Alamofire so I know lots of people are using SwiftyJSON. I don’t know much about the other ones.
JAIM:
Okay. There are some of the earliest writing on people doing Swift app was like, “JSON parsing is hard,” so everyone just went right to SwiftyJSON.
JOSH:
Right.
CHUCK:
I thought you were going to say they went right to XML. [Chuckles]
JOSH:
That’s even worst Chuck.
JAIM:
Swifty XML is like 74th on [inaudible].
JOSH:
[Chuckles] Yeah.
CHUCK:
This way lies madness.
JOSH:
But your point that JSON parsing is hard, I think that’s another misconception that people have. It is still hard but it’s not as hard as it used to be.
Some of the outdated tutorials out there cover how to do JSON parsing in Swift and they use Swift 1.0 or 1.1 when unwrapping optionals was a lot more work and you ended up with this pyramid of doom as it’s known. Today, [crosstalk].
JAIM:
Explain the pyramid of doom. What is that?
JOSH:
Sure. Basically, it’s a series of nested if statements. For example, if I make a request to get some repositories and there’s a repository and a repository has a user and that user has name; if I just want to get that username, I have to write a conditional statement to unwrap the repository. Then inside of that, another nested if statement, I have to write another conditional to get the user, and inside of that, another conditional to get the name from the user. So you can end up with these huge nesting issues that people started calling the pyramid of doom.
That’s no longer necessary today, as of Swift 1.2. You don’t need to nest so much or at all even.
I think a lot of people see these old Swift tutorials about how to parse JSON and see this crazy nesting and think, “Oh, this is terrible. I need a third party library,” when in reality, today, parsing JSON in Swift is not that bad. It’s not how it used to be.
JAIM:
I agree with that. With the pyramid of doom, you needed to nest every required field in your model.
JOSH:
Right.
JAIM:
So [inaudible] how big it was that you needed to do it for all of them. It was pretty painful but without that, with a little better optional unwrapping that Swift gave us, the benefits are not as clear.
I agree with that.
JOSH:
Right. Yeah. So now you can do things like you can unwrap multiple optionals in a single if statement. Or if you care about knowing which properties you were able to parse and which ones you weren’t, and printing out error messages or things like that, then you can use guard statements and do multiple guard statements, one for each property if you want.
With the guard statement approach, you may end up with just as many statements but you get more detail and they’re not nested like they used to have to be in od versions of Swift with if statements.
JAIM:
So how does the guard differ from, say, the if-let we’re used to doing?
JOSH:
It’s basically the inverse of that. So you say “guard let user equal” and then grab your user, then the guard has an else block with it but only an else block. If we’re not able to get our user, then the else block is executed and maybe it prints an error message and then just returns from the method or returns nil or something like that.
So then after that guard statement outside of that but in the same method, then you can use the user without having too unwrap it or anything like that. It’s already unwrapped and ready to go, ready to use.
JAIM:
Okay. So even if it’s not the braces or when you think of [crosstalk] scope, you can still use it as unwrap?
JOSH:
Yes. Exactly.
JAIM:
Okay. So what are your opinions on guard? What I’m seeing from people blogging is that we’re still trying to figure out what the Swifty way of doing guards or if-lets, people are having different opinions with it. What do you think?
JOSH:
Right. One of the things that I like to do is to return from methods early and I think guards allow you to do that very quickly. I can check if something is nil or not with the guard and immediately return from the method if it’s nil and I didn’t want it to be.
I think they’re useful; sure, they can be overused like anything but in general, I’m okay with them and I like them.
ANDREW:
Yeah, I like them, too. The other nice thing about guard is that if you’re unwrapping an optional, in particular the unwrap version of the optional is actually – persist after the guard, assuming the guard does not execute its else. So unlike if-let, you don’t have to – it’s even better for preventing the pyramid of doom.
JOSH:
Right. Exactly.
ANDREW:
This is probably a silly question but some apps have to not only decode JSON but also encode it, turn model objects into JSON to send up to a web service. Is there any difficulty in doing that in Swift?
JOSH:
Probably not as much. I think it’s basically if you can take your model object and turn it into a dictionary, then NSJSONSerialization can handle it from there.
Yeah, I don’t think there’s as much of an issue with that and so that’s not something that’s covered in the book.
ANDREW:
Of course in that case, you're going from a strongly typed world to a weakly typed world which is much easier than the other one.
JOSH:
Yeah, exactly.
ANDREW:
I’m curious about your book. To be honest, if I had been working on this problem and – I had learned a lot about it and solved it for myself; I would not have made the logical leap to ‘hey, I should write a book about all this’. That’s something you did and I’m serious to know, is this something you’ve done before in other books? They’re similar, they’re kind of like this – it’s kind of cool. It’s like a concise little subject book that goes really in-depth on a particular topic. Have you done that before? What gave you the idea?
JOSH:
I co-authored about it before. It was back in the iOS 7 days called Developing an iOS 7 Edge. It was about the new things that were in iOS 7. I really enjoyed that and wanted to then write a book of my own at some point.
This one came about because – from basically doing research and searching the internet and finding this question coming up again and again. How do I parse JSON and Swift? Or why is it so hard to do this? Or things around – in that domain.
So with this book, I wanted it to be very specific about doing that. Sure, I could’ve written about how to fetch data from the network and how to write an entire rest [inaudible] or something like that. But I wanted this, like I said, to just be very specific on one topic. Hopefully, it can be more helpful to people that way because if you're looking – if you’re not sure how to parse JSON in Swift or how to write tests for that or things like that, you can come here and learn that specific information.
ANDREW:
You’ve done something I think is good which is even though there’s information for anybody that has not done JSON parsing in Swift or anybody that has done it and doesn’t know exactly how to do it the best way, you’ve seem to have written the book with a real – like you're thinking about the fact that people who are reading this might be quite new to Swift in general. So you go to pretty good lengths to explain what if-lets are, what optionals are in the first place.
JOSH:
Right. That was one of the things that was tricky for me about this because yeah, there’s going to be – this could be useful to a wide range of developers, whether they’re just getting started with Swift or whether they’ve done Swift for a while and just for whatever reason, haven’t worked with JSON yet.
So it was hard for me to know how much do I explain things versus how many things do I just leave out and assume people know what optionals are, or guard statements or things like that.
Hopefully, it’s useful for a lot of people. If somebody already knows what a guard statement is, they can skip over that paragraph and be on their way.
JAIM:
So one thing that trips up a lot of developers when we were actually getting the data by hand – we fire up NSJSONSerialization, we do the JSON object with data and some of the parameters.
People don’t really know what to do like their reading options. Does it matter?
JOSH:
That’s something that usually, I just pass in an empty array and don’t worry about the options. That’s what it talks about in the book. It mentions that yeah, you can specify options and you can go read about them in the docs, but those are something that I’m not sure I’ve ever used the options other than when I thought I had to specify options. Now that I know I can specify a no option so I just do it that way and it works for me.
Yeah, there may be some value in those but in general, I don’t use them and those are something where if you want to know about them, you need to read the docs.
JAIM:
Alright. Fair enough. I have never really found any real reason to mess with them [crosstalk] but you never know.
The thing – I had a question – more of a style question. We talked about the pyramid of doom but we don’t have to do that anymore. We can do all our optional binding and one thing – one pattern I saw – I’ve started seeing which I initially recoiled from is using – heavily use of the were clause where we could filter things out and not in a [inaudible], we’re just making sure that this type is correct, something like a – like if you have any user, they join in a certain date where the user is past the state. That’s something I’ve always put in, like an if statement.
Do you have an opinion of if that’s appropriate for a were or does it matter?
JOSH:
That’s a good question. I would probably just put it in an if statement rather than using a were, but I
honestly – I haven’t used were that much at all so I’m not sure what – where the value is in were.
JAIM:
It’s valuable if the type – you want to check a type or something, if you’re trying to get something and you want to make sure the type is correct before you move on. [Inaudible] makes sense, but I’ve seen people use a were where there’d be an if.
I don’t know if I’m just being old and grouchy because that’s the way I’ve always done it but you never know.
JOSH:
Yeah. And something like checking the type, that’s something you have to cast to types if you want to do anything useful anyway. I usually use them in the if statement and do the optional cast. Then if we were able to get this data and it’s the type we wanted, then continue on to the if block.
JAIM:
That makes sense. So what parts of JSON parsing are we missing? What have we talked about?
JOSH:
One of the things that I think is nice to do as well as you’re parsing JSON is to use typealias because when you have an array of dictionaries especially, you get these double square brackets and I think that’s a little bit confusing to look at. So what I like to do as I’m parsing JSON is to define a type, maybe called JSON dictionary and that is a dictionary of string and any object. That makes it a lot easier for me to see, okay, this is a dictionary or this has square brackets around it therefore it’s an array of JSON dictionaries.
JAIM:
Definitely. The typealias is something that I’ve come around to more after talking about it with people but initially, I was pretty opposed to it. Every time I run across a type of this, I’m like, “What is that thing?” You gave it a name but I had to look it up. Okay, oh, it’s a [inaudible]. Oh, it’s something. Oh, it’s an array over an array.” But they’re valuable in certain cases.
JOSH:
Right. I think if they improve readability and if – hopefully, if they’re named well, they’re easy enough to understand. For me, using the JSON dictionary typealias is something I just do all the time. Maybe if it’s something that’s done frequently, then it’s easier to just know that this is that type.
JAIM:
Definitely. If it’s something that you use a lot, you can – definitely don’t repeat yourself if anything is up with the typealias.
ANDREW:
I think it’s like anything you can overuse. You can overuse it and make your code hard to read, but when you use it in the right way and judiciously, it can make your code easier to read.
I’ve been using typealiases here and there in Swift. And I actually use typed ifs in Objective-C sometimes, particularly for blocks where you have a block and they’re really verbose and you want to – just a short, descriptive name for a block type.
You touched on this a little bit in the book, but how does writing your JSON parsing codes fit in the overall app architecture? Should you just put all your JSON parsing code in your view controller?
JOSH:
No, definitely not. [Chuckles]
JAIM:
Second takeaway of the show.
JOSH:
Yeah. [Crosstalk]
CHUCK:
Should we put it in a big pile of mess with the rest of the big pile of mess? [Chuckles]
JOSH:
Yeah, so that’s something that we discuss in the book, too. The JSON parsing code definitely doesn’t go in the view controller. Like most things, it doesn’t go in the view controller.
What I normally do is to put the JSON parsing code into just a generic JSON parser class or sometimes more specific like repositories parser class or user parser class or something like that. It’s out of the view controller which then makes it easier to test because view controllers are just really hard to test. Having it outside of the view controller – and its own class makes it easy to pass in some input, get some output and verify the results.
JAIM:
So with that, what do your models look like? If you have a user – or do you have the mapping inside the user – the structure class or is that done elsewhere?
JOSH:
Usually, I would do the mapping inside of a user parser or something along these lines. I’ve seen it done inside of the model class and I’m okay with it; it’s just generally not the approach that I take but I guess I have done it that way in the past sometimes, especially when – then I want to be able to return the user as a dictionary so I can then send up the data. If I’m going to do a post to the backend, send the user data up in a dictionary.
It really depends and I don’t favor one approach all that much over the other, but like I said, usually I use a parser to do that.
JAIM:
Okay, that makes sense. [Inaudible] mean they all often create a builder class or a parser class. I think I’m being overly formal sometimes but I think it’s the solid pattern. I’ve never really had any trouble with it.
JOSH:
Right. One of the other things that the book covers that I think is important is to figure out how you want to handle arrays and nil inside of those arrays. Sometimes if I make a request for repositories and one of them has bad data in it, therefore, I can’t create a repository object out of it, what do I
do about that? Should the array of repositories contain the nil? Should it not be there? Things like that.
What I like to do in those situations is to use flatMap to parse each repository individually in a parse repository method and then flatMap will iterate over the entire array and then remove all of those nil values from it. So that’s something that I found really useful as well.
JAIM:
Very cool. Oh, another question I have – so if you’re parsing JSON, what are the trickier things that we have to do? People have different approaches; how do you handle nested data? Do you have an approach that you use for that?
JOSH:
What I would normally do is then create – for example, a repository has a user inside of it. How do I create the user? Is that the question?
JAIM:
Yeah. Well you have a user and [inaudible] the user’s pet. So you have a pet object inside the user.
JOSH:
I would traverse that and then each time call parse user to get the user and maybe parse pet – to get the pet out of there and then set that on the user and then set the user on the repository.
JAIM:
You have a separate method – so you get the data from the user, pass in to a separate method that would parse the pet.
JOSH:
Right. Basically, each time I’m taking the dictionary that I get from the JSON so there’s a user dictionary in the JSON and then passing that into its own parse user method for example. That parse user method takes the dictionary and then transforms it into a user model object and similarly for the pet.
CHUCK:
Are there good resources out there for people who want to go into this topic?
JOSH:
Yeah. I’ve written a couple of posts on my blog. There are tons of articles in the internet about this topic.
CHUCK:
I hear there’s a book on it, too.
JOSH:
There’s a book as well. Yup. I wrote the book. In addition to the book, there are other – I call them editions of the book. So you can get just the book or you can get the book plus some videos plus sample code. On top of that, if you want a one on one consultation with me, there’s an edition of the book for that as well.
There are a variety of ways to get the information you need from free to the upper tier premium packages.
CHUCK:
Alright. Should we get to picks? It’d be a short one this week.
ANDREW:
Sounds good to me.
CHUCK:
Alright. Andrew, why don’t you start us off with picks?
ANDREW:
Sure. I’ve got three picks.
My first pick is – it’s actually a little app. It’s open source. Super simple. It’s called PlayNow. A couple of things about it, the whole point of the app is you run the app and all it does is it creates a new playground in a temporary [inaudible] for you and opens it in Xcode, a new Swift playground.
A lot of times, I’m working on something or I’m talking to somebody about Swift and I just want to try something out really quick. I have this app in my apps folder; I can launch it with Spotlight or with a launcher. So in just a second, with a few keystrokes, I can have a new playground opened in Xcode and that’s cool to be able to type out ideas.
One interesting thing about it is that it’s – it is a Mac app but what it really is a little Ruby script that – packaged it up in such a way that it will run as a Mac app so that’s kind of cool.
My next pick is VIM Adventures. This is – a month or two ago, I decided I really wanted to learn how to use VIM and I found this game called VIM Adventures that I think is pretty popular but it’s like an old Zelda type game where you – kind of an adventure game. But it teaches you VIM as you go because you have to use VIM commands to navigate and to do text editing, to get past obstacles and solve puzzles and whatever. I think it’s really well done and it’s fun to play and you also learn something.
My last pick is Mondo, the company Mondo. They make all kinds of stuff; they make toys, posters; they have original art, clothes and they have, a few years ago, started doing re-issues on final of music, especially soundtracks. They just do a really good job with their stuff. In particular, when they re-issue a soundtrack, they have an artist do custom album artwork and they’ve gotten really good artists to do really cool artwork.
2:
The Wrath of Khan soundtrack on vinyl and it’s well worth checking out. That’s Mondo and those are my picks.
CHUCK:
Very nice. Jaim, what are your picks?
JAIM:
Okay. I don’t have so much of a pick; it’s more of a life hack.
Chuck, you mentioned that you were [inaudible] changes this year, trying to get into shape. I just wanted to assure the users – the listeners, sorry – something to help me out. In my twenties – early to mid-twenties, I was about 40 pounds heavier right now. I had trouble losing the weight. Turns out the beer at White Castle diet was not the right thing for weight loss but anyway.
One thing that I always had trouble with is I get hungry. You eat how people say you're supposed to eat. Okay, I had a decent breakfast and now it’s 11 o’clock and I’m hungry again. So I just had a life hack.
I always have a healthy snack around. For me, if I had to go somewhere, I’ve got an apple, some nuts or something because if you’re hungry, bag of carrots? Not going to happen. It’s not going to work for me but having an apple or something to munch on because I [inaudible] hungry an hour or two after I eat. That’s just how it works.
If you don’t do that, then you [inaudible] be hungry and then I’ll of a sudden, Joe from accounting brings over a bunch of donuts and there you go. All your will power is gone.
Helps you keep on track because one thing I’ve learned is if you’re using will power all the time, it’s not going to last. It’s January, you’re cranking it out. It’s going great. February comes by, maybe I’ll have a super bowl party. You’ll love nuts and the girl scouts show up then you're done. It’s all over but my hack was just having healthy snacks. If you don’t like apples, try something else.
It’s winter right now so citrus is in season. We have some good oranges and stuff like that but that’s something that helped me out a lot. That’s my pick for the day.
CHUCK:
Awesome. Yeah, those girl scouts, they sabotage my diet every year.
JAIM:
It’s a plot.
CHUCK:
It is a plot. I’ve got a couple of picks here. The first one is one that I’ve been using for a while. I don’t actually know if this works on iOS so if it doesn’t, I’m really sorry but I’ve been using Honeybadger.io to track errors. I know it works really well for Ruby on Rails. I wouldn’t been shocked if they have an API that you can hook into for that.
Another app that I’ve been using for a while to track a lot of these stuff is New Relic and they definitely have iOS APIs. In fact, we had them on the show. I think it was last year or the year before. Anyway, you can definitely check those out. Those are both picks. New Relic does a little bit more on the side of performance monitoring and things like that as well as the error tracking. It’s a pretty nice tool for just tracking down where some of the bottlenecks are in you app.
Josh, what picks do you have?
JOSH:
My first pick is called MVVM is Exceptionally OK. This is an article by Ash Furrow. In it, he addresses the other articles that have popped up recently in the iOS community about how MVVM is not good and it causes other problems. Maybe some people even say that it causes more problems than it solves.
I’m with Ash; I think MVVM is exceptionally okay. I think that concern that a lot of people have is that MVVM just results in moving a bunch of code out of a view controller and into a view model. While I think that’s a good step in the right direction, and as Ash says in his post, that’s just a step in the right direction. It makes it then easier to extract some of the code out of the view model and put it into other classes, maybe in a JSON parser class or in an API client class or something like that.
One of the things that I really like that he says in the article is that he would rather have a fifty line view controller and a 400 line view model than just a 450 line view controller. I’m totally with him there because you can actually test a view model whereas view controllers are notoriously hard to test.
This is an approach I follow in a lot of the apps I build – most of the apps I build. So I think this is a good article explaining what the benefits are and why it’s good.
This leads in then to my second pick because in the expanded edition off parsing JSON in Swift, there’s some sample code for an app that parses JSON in Swift so you can see how to do it in your app. So there’s sample code that uses the MVVM pattern in the expanded edition of parsing JSON in Swift.
So for my second pick, I’m not picking my book but I wanted to offer a coupon code for 10% off of the book. So if you use the code iphreaks, you can get 10% off of any package of the book. Like I said, the expanded edition has the sample code that uses the MVVM pattern. That’s it.
CHUCK:
Awesome. You mentioned the book but if people want to follow up, see what else you're up to, I
know we had you on before and you teach how to build iOS apps courses and stuff. How do people find out about this stuff?
JOSH:
Mostly through my website, roadfiresoftware.com is where I am. I’m also on Twitter @jtbrown.
Those are probably the best ways to find out what I’m up to.
CHUCK:
Awesome. Well, let’s go ahead and wrap up the show. Thank you for coming, Josh, and thanks for our other panelists. [Crosstalk]
JOSH:
Thank you.
CHUCK:
We’ll go ahead and catch you all next week.
[Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]
[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit cachefly.com to learn more]