JAIM: Today on the panel, we have Jaim’s dog!
[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]
[This episode of iPhreaks is brought to you, in part, by Postcards. Postcards is the simplest way to allow you to feedback from right inside your application. With just a simple gesture, anyone testing your app can send you a Postcard containing a screenshot of the app and some notes. It’s a great way to handle bug reports and feature requests from your clients. It takes 5 minutes to setup, and the first five postcards each month are free. Get started today by visiting www.postcard.es]
CHUCK: Hey everybody and welcome to episode 97 of the iPhreaks Show. This week on our panel we have Jaim Zuber.
CHUCK: Andrew Madsen.
ANDREW: Hello from Salt Lake City.
CHUCK: Pete Hodgson.
PETE: Hello from Hollywood, California.
CHUCK: I’m Charles Max Wood from devchat.tv. I just want to give you a quick reminder to go and support the shows by going to devchat.tv/kickstarter and supporting my campaign there.
We also have a special guest this week, that is Michele Titolo.
MICHELE: Hi everyone.
CHUCK: Do you want to introduce yourself?
MICHELE: Sure, I’m an iOS engineer over at reddit. I’ve also done a lot of work over on Cocoa pods. I am CTO and on the board of the non-profit Women Who Code. You have probably seen some of my talks or I occasionally write technical blog posts on different aspects of software development.
CHUCK: Very cool. We have a series of topics that we want to cover with you. Is there a particular area that you’d like to start with?
MICHELE: We can jump in anywhere I guess because there’s a long list to get through [chuckles]
PETE: I think we should start with some HIPster discussions.
CHUCK: There you go.
MICHELE: Some HIPster discussions, okay. So HIPster as in the whole decoupling and deconstructing or large code bases.
PETE: Deconstructionism as it applies to the context of something. Sound like an art major’s [chuckles]
JAIM: We need to wait a while and grow a beard before we have this discussion.
MICHELE: If everyone needs to grow a beard, you’ll be waiting on me a really long time [chuckles].
PETE: I’m tempted to keep abusing my HIPster joke but I’m going to stop now. So what does this topic mean, what are you talking about when you talk about deconstructing or decoupling application.
MICHELE: It means a couple of different things. As a code base grows larger and more mature over time, you start wanting to take out pieces that are really reusable; so that you can make new applications, so that you can open source something or just in general encapsulate some functionality in a very specific way. A good example of this is your networking sect. At reddit we have a lot of APIs, I remember the first time I looked at are list of APIs on our developer website. I was just like “Oh my goodness. This is a lot of calls.”
It can be really intimidating when you’re dealing with something that big. But it doesn’t change very often which is really great. So we’re able to create internally our very own networking library because we know the APIs are stable, we know the responses; we know all of the patterns so we can do that. It’s a foundation not only for building multiple apps but at some point possibly in the future it’s a good component to open source.
JAIM: That makes sense. So we’re talking about a situation where you’re coming into a code base that maybe you’re not that familiar with, that people have been working on for months maybe years and try to figure out, how can we reuse these components, how can we add up to our app, what are the goals?
MICHELE: The goals are at least one I’m looking at making separate libraries; is just separating out functionality because it’s just really nice [chuckles]. There’s not another way to say it. As a code base gets bigger and larger, [inaudible 04:35] does this really well. There’s just a ton of libraries internally that have just been separated out because everything is super encapsulated. It makes things a little bit harder because “I need to fix this bug in that library over there, because it’s happening in my app.”
But it also means you have versions of those things back to the networking thing. If there’s a new version of an API that comes out or the payload changes or they produce a new error code, you can discreetly update that and make sure that you’ve captured both the old functionality in your history and previous versions of the library as well as moving forward. You can explicitly say “Okay, we’re going to be using this new key for your new error code.”
Then when you get to the point where you’re having multiple apps; I did this when I was working on my last job on Threadless’ two apps. We had a log, check out flow so threadless.com you buy t-shirts and the checkout flow for the two apps were pretty much exactly the same. There were some styling differences but we were able to share a lot of that code to one, make sure that the experience were consistent between both apps because when users download two apps by the same company they expect it to be pretty similar. Then at the same time, we only had to write it once, which is really great because then you can move faster. Especially in the whole consulting client work; speed is really important. It just lets you work better, and be more explicit about when we change things.
PETE: So in that case of even those cases with the network libraries. What was the mechanism for teasing those apart, did you start off knowing that you were going to eventually want to have a separate library, or was is build it and then realize like “This is [inaudible 06:20] piece that we should be extracting.”
MICHELE: It varies on where you are in the process. I’ve done a lot of apps from scratch, that’s the thing when you do client work. Client comes over and it’s “We want this for our new app.” They don’t usually care about that as much, so if it’s something, short timeline, they just a want it done, it’s less important unfortunately to them for you to spend extra time doing that but if you’re working at a product company and you’re owning something. The earlier you start thinking about this, the better. Just because over time, I’ve don one of the other apps that I inherited at a previous job had a really tightly decoupled section that we were like “We should clean this up, get it out into its own thing,” because it was its own component that they wanted to share between a couple of their apps.
Just going through and cleaning up imports, it took a while because this imported thing we wanted to reuse, imported this other header file that we needed for a specific reason so you have to figure out “Are we using this other little chunk too? Do you have two different libraries because they share code?” The earlier you can do it, the better because then you don’t have the problems with the thing you want to take out depending on everything else that’s already in your code base.
PETE: Yeah I’ve definitely seen that before. It’s like a big snarled mess and it’s like pulling a thread out on a sweater, you start off with “I just want this one piece here,” and before you know it the entire sweater is on the floor. You have to figure out how to knit it back together again.
MICHELE: Yeah, and if you’re doing something like the threadless.com check out that was actually a fantastic example because there was a lot of styling that had to happened and the two different apps were using, I forget which one of the apps pulled in a pod for making working with friends a lot easier but the other app didn’t have that. So it was like “Okay, we want to use this library so then you have to go through and add that as the dependency on the private pod that was a shared code. And go through and clean up the imports just to make sure that the little component could compile on its own instead of pulling in a font category, and a color category and all of these other things. It’s a little bit more time but it save a lot more time later.
PETE: So would you advocate – let’s say I’m on a Greenfield project today I work for a company and they decided they finally are going to get around to building an iOS app. Would you advocated for going all the way to actually starting in separate libraries for separate things or is it more structuring the code so that there are some seams that you could slice up once you get to the point where it makes sense to make a library?
MICHELE: Seams are always really nice especially when you’re working on larger teams because you step on each other’s toes less. You can have one person doing the model layer, another person doing a bunch of UI stuff. You don’t end up having massive project cloud conflicts or you decide that “We’re going to decide the naming scheme for our private methods to have an underscore,” you’re going and changing the same files because that just – no one likes dealing with merge conflicts.
Whenever I start an app, it’s how much can we separate out stuff as possible regardless whether or not you plan on compartmentalizing things. Because I’ve seen some five, six year old code bases that don’t have any of that and when you go on and change on thing, but it turns out there is this other thing over there that depended on it. It’s just really messy and really tightly coupled. So doing anything like that is like tearing your hair out because you’re like “I just want to have a custom text field so that the text field is always styled the same.” That actually turns out to be a lot of work, when you’re just moving really fast, and just be like “No, we just need to get it done.” Just put it all in one view controller class [chuckles].
There was a good article a couple of weeks ago on the mass or I think a talk, I’ll find it and put it up on the picks section – about a massive view controller and some strategies for making that less of a problem because it is a problem [chuckles].
PETE: The way I talk to people about that to try and encourage people that decoupling stuff is good is; our goal is to make, arrange the software so you have to hold it as little as possible in your head at once in order to make a change. So if you want to change the size of a font, is you don’t have to understand the entire app and reason about what that change is going to make across the whole app just to do that thing. You want to limit the amount of work your brain has to do in order to make each of those little changes.
JAIM: I think it’s important to say; dealing with these massive view controllers after hacking code in there for two years, is very painful. I’ve done it, and until you dealt with the pain you don’t really understand how important doing things that we’re talking about here is.
ANDREW: When you’re working on separating your stuff out, decoupling it or deconstructing it, how do you – I’m trying to figure out how to phrase this question. How do you think about things, how do you inform your own choices so that your code is reusable is factored the way that we’re talking about? I’m thinking about how you put yourself in the right mindset or approach problems.
MICHELE: It’s really about looking ahead which is hard to do sometimes, as everyone knows [chuckles]. You look at the app that you’re building and you overtime just like as you become a more experienced developer you start to notice, programming patterns, and solutions to those problems. You can also start to identify the places where you can draw that line, things that are not working, data persistence, models. Those are the easy ones where “We’ll have a library that contains our app models separately because we know –” Hopefully your API doesn’t change that much, a lot of time it does but you can encapsulate that separately.
But as the app gets bigger and you go through and start building a bunch of things, my rule of thumb is if I have to do something more than twice, then it deserves its own class, category, library. If you have a bunch of table views that all look the same, make that something separate, make that reusable because it’s going to save you time. So that’s my rule of thumb, which has worked out pretty well [chuckles], because then if you do something only twice it’s like “Well, okay there’s a little bit of copy, paste here but it’s only in two places. They’re still different even though they might look the same or have some stuff in common,” third time’s usually the charm.
JAIM: I will say it once, and I will say it many times, copy, paste is code reuse [chuckles]. One time is fine, two times, no.
PETE: Copy, paste inheritance.
JAIM: Here we go.
ANDREW: I’m actually with Michele on that though. There’s a good argument to be made on using something twice is still under the bar where the extra work and complexity takes to factor out is worth it but more than that, it’s hit that bar.
JAIM: I think that you can do premature optimization very easily. You have things that are similar but are only incidentally similar; they are actually very different and will expand in different directions. But if you wait two or three times before you extract them out, then you’re in a lot better shape, but if you do it too soon then things get complicated. You can over complicate what you’re trying to do.
CHUCK: I’m curious though, I’ve worked on some systems that had things that are highly coupled and when we started refactoring things out it was exceptionally painful and so is there a point you can get to, to where maybe two times isn’t quite enough to justify the refactoring?
MICHELE: It is very depending on the situation, every code base is different. Every code base has its different established for doing things. If the code base was written in such a way where there’s not a lot of inheritance. For example, I’ve built apps that have a view controller base class that does some really basic things like every view controller tends to make that work request, so we’ll put that in a base class. But if you’re working with something that doesn’t have that, you have to be really [inaudible 4:30] [chuckles].
It’s just drawing the line and saying; how similar are the used cases for these things and is it going to take us more time to make this thing flexible enough for all of those use cases, rather than just special casing it. I find that a lot of time, you can do it partially, so you can have a network section manager that you have a base view controller, like a network view controller and it only has a reference to a section there [inaudible 15:02]. That might be all you really need, but there might be things where “Every time we to show this kind of screen, and there’s four different ways we can show it. We do a lot of the same stuff.”
You just have to be able to see the reused patterns within your own app. I find that, when you have a really good product spec and a really good user flow that you can work from, it helps immensely with this thing. Because then you can see “We have three table views that look almost exactly the same and are showing the same data.” So, easy but sometimes you don’t know. So you just have to go in and be like “What’s common, what’s going to be useful to have everywhere?” But then it’s all so optional. So if you have a network view controller class, you don’t have to use that in every single view controller. There can be exceptions but then it’s just figuring out what you want that to be
JAIM: I think one thing you mentioned that’s very important, and it gets lost on people that there are no perfect patterns for doing this. It’s all dependent on the app that you’re building. You might have a lot of repeating things that on a different app you may not be repeating. So it’s important to code your patterns around your app that you’re actually doing; what parts change fast, what parts don’t get touched.
CHUCK: There are different kinds of similarities too, some of them are; this behaves just like this other thing except for maybe one or two instances. In other cases it’s; it’s doing more or less the same thing but it operates on a different type of object or a different class. So you have to look at those different things and deicide, the first case works really nicely for inheritance. It acts the same except for one or two exceptions so I’m just going to inherit and override versus the second case where maybe you might want to do something that’s a little more akin to dependency injection.
MICHELE: This is also where something like the decorator pattern can be really useful. We love categories, so just giving yourself – it’s a little bit sometimes dangerous because you’re creating a category [inaudible 17:05] which some people don’t like doing that. But in situations like this where you really want to create flexibility, categories are fantastic because you don’t have to use it. It’s there and you can use it when you need to but you don’t need to go out, create base class or an entirely separate to be able to do this one thing all the time which I do a lot for loading states so a lot of apps still have a pretty standard [inaudible 17:31] to show on your loading. So you have either a class in a view controller or something else, where you’re just like “Hey, configure this for a loading state.” [Chuckles] Because they’re pretty much the same, it’s nice to be able to change once and then change everywhere which also let you go a lot faster.
JAIM: So let’s step back a bit, what is the decoration pattern?
MICHELE: In Objective-C they are categories, which is our most commonly way of using a pattern. Decorator is adding methods, properties to specific objects without actually creating a subclass.
CHUCK: So do you wrap it in some kind of wrapper object that passes through everything except things that you care about?
MICHELE: Not usually, it’s usually just like “I’m going to create a new method on UI view controller that show loading view.” Then you just import the category and use the method that you want or not use it. If you don’t import the category, you don’t have to use it. One screen has a different loading view; you can just not use it. But it’s available to all UI view controllers then.
ANDREW: What you asked about is usually called composition.
ANDREW: It’s really for a different scenario.
PETE: I’ve got a really dumb question or maybe annoying question is; is there any mechanical reason why [inaudible 18:49] is tricky to use in a library? I think you remember there’s something where if you include a [inaudible 18:52] but you don’t include a library that has a [inaudible 18:55] you don’t use it and it doesn’t show up. There’s something like some weird Objective-C where [inaudible 19:00]. Am I imagining that or misremembering it maybe?
MICHELE: I know that there are some problems with naming because Objective-C isn’t exactly essentially [inaudible 19:12]. So if you create a method and a category that happens to override a standard method or override a method you’ve had yourself, then it just has funky implications because it’ll be implementation that will be used is the one that is loaded last. There’s no guarantee of which one’s will be loaded first or last. That’s usually more of a concern rather than the whole importing problem. Especially in terms of we don’t know what internal categories Apple uses [chuckles]. So if you accidentally override a method that is an internal Apple one, that’s kind of a problem [chuckles].
JAIM: Actually, I found an internal category once, the wrong way. It’s not a secret internal category. Way back in iOS 3, they didn’t implement a first object on [inaudible 20:03]. So I was working with some code that “I’ll just implement this,” and left it in. they didn’t fix the case where there are no elements so it just crashed. It worked fine up till iOS 8 and the app just started crashing. That was about it, one day debugging session.
ANDREW: I guess in that case, the category method because first object was in foundation since iOS 4 maybe even. Maybe they moved that out of the category and into the class and so your category was now overwriting that where it wasn’t before. That’s certainly a problem.
Pete, the thing that you brought up first I think that if you build a static library with a category in it, you have to get past the dash obj c.
PETE: That was something else.
MICHELE: It’s by default set, when you import a static library. It doesn’t define link or symbols for each function. [Inaudible 20:52] do this, which is why every time you’re using something like CocoaPods if you go through and actually check the xcconfig that ends up coming in. you’ll pretty much always see the obj c compiler flag.
PETE: That’s why I remember, I discovered this a while ago CocoaPods when every single library that you used had instructions in the read meter; go here, type in dash obj c and type in dash all in underscore and all sorts of other stuff that we don’t have to worry about [clear 21:27] CocoaPods.
ANDREW: Now we have Frameworks right? So we don’t have to worry about [crosstalk 21:31]
MICHELE: Which is nice [chuckles].
PETE: So I’ve got a question [inaudible 21:36] you hint that this [inaudible 21:38] talk about sharing, there’s different kinds of things that you can extract or reuse across applications – on the one extreme on stuff like the network [inaudible 21:47] which is the bottom of the stack if you will but then you also mentioned sharing UI across applications. I was actually a bit surprised to hear that you’ve done that where you’ve extracted bits of the UI into a library, is that feasible, I guess it’s feasible, you’ve done it but is it more painful to do that than extract [inaudible 22:07].
MICHELE: It can be really painful if you have two different teams working on separate ops but share UI code, just because people forget these things, they forget that it’s used sometimes. You just add another import header then all of a sudden the other op can’t build it. But in terms of, it’s more of a people problem than an actual code problem. Because if you are sharing something like a UI code, hopefully you have a style guide and conventions and good foundation for what good code looks like and what patterns that you like as a development team.
So it shouldn’t be foreign. Like one app for example is using ReactiveCocoa and then VVM and another app isn’t. Well [chuckles] you probably should talk because as teams get bigger, people move around at companies they work on an app, they work on another app. So you want to have your things internally to be as consistent as possible. If you’re doing that and sharing something like UI code is pretty easy. There are some definitely some [inaudible 23:13] just because if you want to share a story board or a nib then you have to have a bundle, then you have to load stuff on a bundle, you need assets and all of those things. It complicates things a little bit more so it works better if you’re providing all of your UI code by hand which people still do. I’d say it’s more of a people problem than a technical challenge.
ANDREW: That’s been my experience too but I think the Framework support in iOS 8 does make some of this particularly related to UI code easier because you can put assets like nibs or story board or images into your Framework resources.
MICHELE: Absolutely. Frameworks are going to make some things a lot easier for sure.
ANDREW: That leads me to something I want to ask which is as we record this, I think maybe just yesterday; CocoaPods has pushed out a new release that adds Swift support, it also adds support frameworks. So what are some of the mechanics of actually sharing code between apps that you use, just dump this source code in both projects, some modules, CocoaPods.
MICHELE: Please no submodules [chuckles] especially because once you get to the point where you have submodules doing any sort – more than one level deep dependency management with submodules. I think everyone has a story to tell on how that’s just been a problem. I am a huge fan of private CocoaPods. There’s two different ways that you can set this up, and whether or not you use Frameworks is entirely up to you. It’s now an option so you can look at what libraries, how the new libraries work, see if the new Framework stuff is cooler. If you’re using Swift, you need to use frameworks.
The two different ways of using CocoaPods internally without public having your pod live on the open source repositories is – so the first one is the super simple one. Which is you have git repository or it could be Subversion or [inaudible 25:12] and then in the root of the repository you have pod spec and then you just work as you normally would build as a library. You can have a simple project and then the pod spec just has the normal information that you would need to add that to a project.
There’s a good guide on the CocoaPods guide site on how to create a pod spec. I think we’re redoing it soon, to make it even better. You have your pod spec that’s just living in the repository and then when you want to use that in your pod file and the projects that you want to import that code into, you just reference that git repository and usually a tag. Because one of the really good things about using CocoaPods is everything is tied to a version number. So if you’re writing a networking library and a payload changes, you can bump up the version in the pod spec, update the tag, go back to your project, change what tag you’re looking at run pod install and it’ll run the newest version.
So that’s the simple way without having to worry about all of these other things but it’s still weird if you have a private library that depends on another private library because you then have to import both of them because it doesn’t see the second one down as well. In that case if you’re starting to build up a large number of libraries and you have libraries that depend on other libraries then you can make your own spec repository. So kind of like the CocoaPods spec repository on GitHub.
You can create your tiny internal one, please do not fork the main one [chuckles].people actually do that, you don’t need to fork the main one, you can just add another spec repository via the command line and then it’ll download just like it does for the master repository. Till download all the spec so you’ll be able to declare your dependencies just like normal. You don’t have to do anything special, just work like if you were working like you were using something open source but it’s close source.
JAIM: So if you have say one app you’re working on and you want to break up the components for a different application, what’s the process for getting the code out there, you create the spec repository, and you create the spec? How does that work?
MICHELE: It depends on how you want to structure things. I’ve done private pods where the source code for it lives inside of an actual app repository but that you tend to have the people challenge where someone would be working in a class that’s used by another app that’s [inaudible 27:42]. And they’ll import something from the app that’s not actually supposed to be in the pod and then you have problems building. So what I like to do is create a separate repository for the reusable and then have both apps point to that one.
There’s ways to do it where you can still keep history but usually what you end up doing is taking it out of the first app, doing an initial [inaudible 28:07] to a new repository and then just having both apps update their pod files to connect to the new repository. Then also helps because then you’re not dealing with mixing up your tags. So usually, at least in the environment that I’ve worked in every time we do a release, we add a tag. So that we know this version is going to the app store, we want to concretely be able to see the code again at the app store version.
So you create a tag but private pods also use tags, or pods in general use tags. So then you’re mixing in the app release tags with the library release tags and that just gets a little messy over time. So I generally like having the code in a separate repository. Whether or not you don’t create your own spec repository depends on how many libraries you have and how dependent they are on each other. So did I answer your question?
JAIM: Yes. I was just wondering because I did a lot of weird things trying to do this the first time I did it. Do you have any lessons learned on easy ways like patterns to take, break up small functionalities because once you decide that this model class we’re going to use other apps, do you have any steps that you learned?
MICHELE: I find it easy when working on a new or trying to refactor out a component is to get the code separate as soon as possible; even if you’re just creating a new Xcode project and just literally copying files over. Because the tools that we have for detecting imports that shouldn’t be there, other class dependencies that we might not be aware of the first time through. As soon as you isolate the code, those problems become much more apparent. So it’s a lot easier to go through and say “Looks like our models are actually making calls to the network.”
So if we want our models to be separate from our network, we’re going to need to figure that out versus, you are doing it in the same project but the thing is still building because the other class is still there. So separating as early as possible and then there is a way to do a local pod using the path option. I’ll make sure there’s a link to the guide on private pods and the show notes so you can have just files on your computer and you can have them linking in as a CocoaPods but you can still actually edit them in Xcode, and have it be your real stuff instead of your editing the code that was downloaded, which you’ll commit and then you’ll update then you’ll run pod install and then your changes will be overridden because it re-downloaded from the net.
JAIM: I get in the state where I was fixing something in the pod then I had copied and past what I fixed into my actual repository, pushing that up and downloading again. And it sound like in a local repository you don’t have to do that.
MICHELE: The path is your friend; it’ll make your life much easier.
PETE: There’s something that I’ve seen in a ton of different ecosystems is that same problems with Ruby, with jam and with Java and [inaudible 31:11] is that getting a nice workflow for switching between consuming a library that someone else is working on versus wanting to make a little tweak in the library and it always feels like it’s slightly clunky. Do you know what I mean, like switching between I just have a dependency and I have to pull it down and then use it and then oh, wait I have to make a small change but I also need to make sure that it’s synced up other changes, other people are making in the same library. I think that’s one of the frictions that you just have to deal with when you are decoupling.
MICHELE: Yeah, then it’s also; you can mitigate that by doing something like having a really good code to reprocess. The way that I’m used to working is regardless of what your changes it always goes on poor request. I think the only time we pushed directly [inaudible 31:57] is when we’re updating tags because it’s a tag. Everything has to go through that process and then as you’re doing small bug fixes, you can either have a local copy checked out or there’s a way to skip over using a tag and just always download the latest copy from the repository. You can work either of those ways, until you fix all the bugs and everyone agrees “Okay it’s time to bump the version and then update the library and the apps using the library to the newest version.
PETE: How would that work with the [inaudible 32:26] if you – so let’s say I’m working on my app and in order to complete some pieces functionality, I need to modify the shared library. If I’m not able to do that and push the change directly in to [inaudible 32:39], does that mean on my app I would point to a –something in a branch while I’m waiting for that pull request or would I just have to wait for the pull request to get merged before I can push my changes to the dependent app.
MICHELE: Yeah, you can specify a source for a pod by a tag or branch or a commit, so you can choose what is best for what you’re doing. If you’re constantly iterating, something like a commit’s not probably the best. So then you can just specify a branch and go through. Every time you’re on [inaudible 33:11] it’ll get the latest commits on that branch. It defaults to master so you just want to get the latest on master, you can also do that. There’s definitely ways to do it, it’s just a lot of installing pods [chuckles]
JAIM: So I should ask the question; CocoaPods, you can [inaudible 33:27] to source or not?
MICHELE: I used to be in the camp of “No that’s a terrible idea.” And then I started having people like designers and product managers wanting to build on their own devices, which some people would be like “That’s a terrible idea.” When you’re moving really fast, sometimes you don’t have time to spend 15-20 minutes to cut and you build, upload it to your distribution, do the version bumping all of that stuff just so they can – the designer can go and double check that the screen you’re working on is pixel perfect. So having them check into source is useful in that situation.
Also, again you’re going back to the whole release tagging if you push a version up to the store then you are doing a bunch of work, you’ve updated a bunch of pods. Yeah, you can go back in time and then once you’re at that tag that was the release and then rerun pod and [inaudible 34:24]. There is a very slight chance that a source might be removed, especially if you’re using a closed source library, Google analytics – actually no, not Google analytics.
There are some companies that will only let you download the newest version of a library. Google analytics doesn’t do that anymore. So that can also be a problem [chuckles]. Because now there is this third party library that you’re using but you can only get the newest version and the version that shipped with the app is different, and the APIs are different so then you’re not compiling.
There are definite benefits to checking pods and I’m now in that camp. When I was in the other camp, it was really quick to clone we don’t have to worry as much about the sizes of your repository. One company I worked at, we were actually hosting our own git server so that was something we cared about. But now I’m firmly in the just check it in but we always make sure that that’s done and [inaudible 35:22] is always has its own pull requests. I haven’t seen any tool for looking at pull requests, GitHub, Git Pocket or any apps that can properly hide the pod’s folders changes. So it will be like looking at this pull requests, and they’ll be like a bunch of changes and then depending on the size of the pod anywhere between 5, 10 files and if you’re pulling in a big one you can sometimes have 100 files.
JAIM: [Crosstalk 35:52] Networking.
MICHELE: It’s just noise when you’re trying to actually do a pull request. So we’ve started just making those separate, and if you’re adding a pod then it just its own pull request. If you’re integrating a pod, if you’re adding it and you’re integrating it, you want to do that in one pull request then they need to be separate commits. So that they reviewer can just look at the commit that actually changes your code, instead of looking at all the pod stuff because there’s still no way to hide it unfortunately [chuckles].
JAIM: That’s a smart approach; I just scroll down forever on GitHub.
MICHELE: Yeah, I’ve had the problem where we added one pod one time that had dependencies so the pull request was just too big for GitHub to show all the files. It was not showing files that were actually changed by developers, like the actual changes we’ve integrating were missing from the thing that was showing. So it’s not just great.
JAIM: It sounds like a good way to pass bad code through; “Looks good to me.”
MICHELE: It unfortunately is, I do not recommend doing that though.
JAIM: It’s the nuclear option.
JAIM: Another benefit of committing your pods, one thing, you can go back in time a lot easier if you want to get bisect. But when Xcode changes, pods changes; then you don’t have that dependency and everyone having to be on the same version which could be a pain. Or the build server having to be on the same version, you get one person who can be the pod master, add whatever they need to add and go from there. So it simplifies the team dynamics around CocoaPods which can be a real pain especially with Xcode updates.
MICHELE: You still have some of the problems between Xcode versions like; you open a story board or [inaudible 37:40] and they’re going to update that stupid version number [chuckles]. It won’t go away completely, different version of Xcode sort through different warnings especially if you’re doing Swifts, everyone on your team needs to be on the same version of Xcode because you’re then working with different versions of Swift. So unfortunately Xcode is still the [inaudible 38:00] hurdle for large teams [chuckles].
JAIM: This is true.
PETE: I would be so much happier if they separated out the compiler, the dev tool chain from the UI. It’s so stupid that we have to download this huge 4 Gig app essentially to update the compiler tool chains probably about 20 max, why can’t we just keep that and check into the repo?
MICHELE: Yeah, [inaudible 38:26] [chuckles].
PETE: I’ll give it a plus one.
ANDREW: What do you want us to do Pete?
PETE: I want you to listen to me whine. It was with Swift crashing.
JAIM: What’s with that?
PETE: It drives me bonkers because I’m so used to – the way I would solve this in other ecosystems is I would use a virtual machine. I would just deploy all of the dev tooling to the virtual machine and everyone uses the same virtual machine, and you’re done. You just can’t do that because of Xcode, it’s all Xcode’s fault. Are you listening Apple?
MICHELE: [Chuckles] it helps.
PETE: I’m going to make a t-shirt or a sign and just drive down to Cupertino and stand outside like a crazy person. I’m not sure if that will work.
MICHELE: You’d have to find the right building because I don’t know what building the dev tools are in [chuckles]. There are a lot of buildings and now there are satellite campuses because they’re over growing. You need to-do a little bit of research.
PETE: When’s WWDC this year? I could just get a t-shirt printed and just hang-outside Moscone.
MICHELE: Yeah, you totally could.
PETE: Just yell stuff to anyone who’s got one of those I’m an apple person badges.
ANDREW: There are people like that outside of Moscone.
PETE: Right, I was just thinking that. That’s just basically just a fine San Francisco.
ANDREW: You might be the only one yelling about Xcode complaints.
PETE: I just need to get Xcode t-shirts printed and then just give them to all the crazy people in San Francisco.
ANDREW: Yeah exactly [chuckles].
JAIM: I like your style.
PETE: That will work. So I had I think we touched on this a few times as we’ve been talking about this but there are a lot of team collaboration aspects to this. Have you ever seen – so I’ve been really getting into this the Spotify model of arranging teams recently. One of the things that Spotify say they do which sounds crazy but apparently this is what they do; they have a team that owns the search bar and they have a team that owns the playlist. Not just like the playlist as a concept but that area of the application.
Do you think it’s feasible to do that with an iOS app with these kinds of tools. Where you could literally have – let’s say it’s a huge app, let’s say it’s [inaudible 40:41] the Spotify I guess on iPad. So they just separate out each of the different part so the same screen and put them into different CocoaPods, or is that just crazy talk?
MICHELE: [Chuckles] That would be a really interesting way to do it but I could definitely see the tool becoming a bit more cumbersome especially when you’re trying to do quick iteration. There’s definitely ways to solve those kinds of problems. I’m pretty sure every development company does it differently because team structures are different. Obviously the code bases they’re working in are different they want to work on different things because software is not the same everywhere.
So there’s definitely pieces that I think could benefit from that like if you’re working on the Spotify app, and you have different ways of getting to a screen that does streaming, having that being encapsulated because “Oh, we’re on the radio” I don’t know how this works of course but you’re on the radio team but radio also need to stream music and streaming is a different team. Being able to see how to connect those two pieces, and also seeing things like documentation on “This is how you start a stream; this is the method that you should use to present. A view controller that shows a little thumbnail of the album and a little play button.
So there are definitely opportunities but it really depends on a lot of other people things. Having an app that is entirely CocoaPods I think would probably drive people crazy [chuckles]. I need to make a change so I make it in a separate repository. Then I update the main app that just uses it; that just seems, that would be cool though now that I think about it. I want to just have fun with that.
ANDREW: I’ve actually tried that with an app that I worked on. I didn’t end up liking it.
PETE: It sounds cool right? The app is just a shell and then you just plug in a bunch of stuff. I can imagine it being, if it was a huge app and only wanted to do was to focus on just your part of it, I can see it being helpful. But probably not down to the scale of an individual like the search bar. That just seems crazy.
MICHELE: Yeah but things are just different when you’re at a large scale and you have a lot of people.
PETE: Yeah, things that sound crazy become less crazy when you’re at the scale of Facebook or something like that. Loads of the stuff they do sounds ridiculous, I guess that makes sense with those guys.
There’s a really good talk by Kent Beck I just watched the other day where he talks about software G forces. The theme of the talk is the practices that you use and that would include how you use CocoaPods. What makes sense when you’re releasing once a month doesn’t make sense when you’re releasing once a week and then what might make sense when you’re releasing once a week doesn’t make sense when you’re releasing once an hour. So he talks about the speed at which you’re building software or at least the speed of which your iterating on the software really changes stuff that makes sense in one context, absolutely doesn’t make sense in the other context and vice versa.
CHUCK: Alright, should we do some picks?
CHUCK: Okay. Pete, do you want to start us off with picks.
PETE: I’m Googling for that Kent Beck talk, sorry I’m Bing-ing for that Kent Beck talk.
CHUCK: Bing-ing huh?
MICHELE: You’re not DuckDuckGo-ing?
PETE: I still need to go into DuckDuckGo, I see all these cool alpha geeks go into DuckDuckGo and I feel like I’m missing [inaudible 44:22]. I guess I’ve got – I’m beginning a bit boring today and have picks that are related to the topic.
I’m going to pick two different books; the first pick is a book called Refactoring by the inevitable Martin Fowler. This is the original, I don’t think he actually coined the word refactoring but this is really – it’s very old now but in software terms it’s probably like 20 years old or 15 years old. It basically talks about all of the mechanisms you can use to tease apart your application. Assuming that you’re not starting from a Greenfield, you got a Brownfield app and you’re realizing “Oh look at that, the networking code is spread throughout my entire code base. How do I restructure my application so that I can [inaudible 45:06] and code out to a library?” Refactoring if you haven’t read the book is a good place to start.
The other book is along the similar lines is amazing book by Michael Feathers called Working Effectively with Legacy Code. He talks a lot about taking an [clear 45:22] getting it into shape and all the semi horrifying tricks you sometimes have to do when you’ve got this old code base and you realize you need to restructure. So those are two really good books.
It just occurred to me I might as well just throw in a third book because I’m on a roll. Refactoring to Patterns is another – a really big, really long but a little bit dry to read but that takes the refactoring idea and focuses specifically on how to introduce a design pattern. Where there isn’t one before. This book came to me when we talked about how do you introduce a decoration. There’s load of details, detailed work it downpours in that book. I think it’s in Java or something boring like that but most of the patterns or most of the techniques still apply regardless. There you go some boring but maybe helpful picks for this week.
CHUCK: Cool. Andrew, do you have some picks for us?
ANDREW: Sure, I’ve got a few picks today. The first one is a WWDC session that’s from 2010, but it’s mostly still very relevant. It’s called API Design for Cocoa and Cocoa Touch. This is a section that Apple did about designing APIs as a developer. It’s mostly about naming convention and structure and they’re talking about how they design Cocoa and essentially why you should do the same things. Some of this has changed a little bit since. Of course Swift sort of changes things because this is all about Objective-C but I still think it’s interesting and pretty valuable.
Next is a bunch of slides that I found looking for that talk and they’re Michele’s slides from a presentation she gave but I thought they were pretty interesting. I wonder maybe Michele can chime in if there’s actually a way to see this presentation. I can’t figure out where it came from. These are just the slides but anyway it’s a talk she did called Cocoa Design Patterns in Swift. So it’s talking about new stuff that’s specific to Swift how it can be used with Cocoa to do cool stuff.
MICHELE: I think that video is up on 360iDev’s website. I will look for the link.
ANDREW: And then lastly continuing on with the recent trend for me it some fun historical technical stuff and this is not exactly historical. I think it’s basically abandoned; it’s a project called the Cocotron. The Cocotron is essentially a reimplementation of Coco for Windows. So you can port your Objective-C Mac app to Windows. I actually used this for a real project several years ago. The main thing I like about this is just it’s really impressive because this guy who wrote it has re-implemented Foundation and AppKit and other APIs on top of the Win32 APIs. It’s all open source so you can read through; see how he did that which is sometimes instructive. That’s Cocotron.
I’m also going to link an article from Matt Gallagher about how to architect your app that you’re going to make cross platform with Cocotron and some of that is actually generally applicable to factoring stuff out and decoupling and deconstructing it. So those are my picks.
CHUCK: Alright. Jaim, what are your picks?
JAIM: Pete, you stole my pick.
JAIM: I was going to pick Michael Feathers; Working Effectively with Legacy Code. It’s a great book for working away old code bases. Most importantly for giving you permission that seem a little bit wrong like some other refactoring in [inaudible 48:40] seem like ugly but he gives you permission. They’re a good idea so it’s okay.
So I’ll do a beer pick instead. The other day I was at – to see the Prairie Home Companion at the Fitzgerald Theater they didn’t have many beers there. One I hadn’t had before was Zombie Monkie by Tallgrass, very good porter and if you put a zombie in the title my hipster flag goes up that you’re over marketing something that doesn’t taste good but this is an excellent beer [inaudible 49:11] porter. Pete, can you get Tallgrass?
PETE: No, I’ve never heard of that one.
JAIM: Alright, I out-hipstered Pete today, I win.
PETE: Well done [chuckles].
CHUCK: Achievement unlocked.
JAIM: It’s pretty underground you’ve probably never heard of it. Zombie Monkie, it’s out of Missouri, I think St. Louis so very good, Tallgrass Brewing.
Those are my picks.
CHUCK: This week, I was at a couple of conferences. None of them are very applicable to iOS development in particular; I was at MountainWest JS, ng-Conf which is for Angular, then MountainWest Ruby conference. Overall I just want to pick getting out and participating in the community. I spoke, kind of, Adventures in Angular did a lunchtime panel at ng-conf. it was just nice to meet a lot of people. I don’t get out to a lot of iOS events and I’m trying to change that. So if there’s an event that you’re going to that you like to see me at. Let me know then if it’s doable then I will try and be there.
I’ve also got a couple of books that I’d like to pick. I’ve become this awful audible junkie so I’ve been enjoying the Ursula K. Le Guin Series, The Wizard of Earthsea is the first one, The Tombs of Atuan is the second one, and I’m listening to The Farthest Shore. I’m really enjoying that. I’m also listening to the Pixar Touch by David Price. That one was also a lot of fun to listen to since I was driving to and from downtown Salt Lake like six days out of the last eight. Those are my picks.
Michele do you have some picks?
PETE: I do, one is the article about massive view controller, it’s called; 8 Patterns to Help You Destroy Massive View Controller. It goes into a couple of different ways that you can think of separating your code.
The second one is in the latest Objective-C I/O issue and it is on how the Artsy team has open sourced their app and it goes into some technical detail on how they broke things up and the process that they used for getting to actually having a fully open source app. I just thought it was really cool.
CHUCK: Alright, very cool. Well, thanks for coming and talking to us. It was a lot of fun to explore all of these different areas of development.
MICHELE: Yeah, thanks for having me.
JAIM: Thanks Michele.
CHUCK: Alright, we’ll wrap up and we’ll catch you on next week.
[This episode is sponsored by MadGlory. You’ve been building software for a long time and sometimes it gets a little overwhelming. Work piles up, hiring sucks and it’s hard to get projects out the door. Check out MadGlory. They’re a small shop with experience shipping big products. They’re smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter @MadGlory]
[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]
[Would you like to join a conversation with the iPhreaks and their guests? Want to support the show? We have a forum that allows you to join the conversation and support the show at the same time. You can sign up at iphreaksshow.com/forum]