Tools to Make Software Less Dysfunctionally

Someone on Twitter the other day sent me a message asking me what tools I was using when making apps for things like issue tracking, testing, managing tasks in a project, etc. I don’t know if I’m the best example of anything, but I can tell you what’s worked and not worked for me in the past.

You Need to Write Things Down

The biggest issues I’ve had working with others have come when the team isn’t on the same page about what everyone needs from everyone else. Having a daily check-in where everyone gets together isn’t a bad thing, but it’s not a replacement for having an issue tracking and project management system in place.

If you’re thinking this can all happen in email threads: you’re wrong. An email thread is a terrible place for this sort of discussion to happen. People don’t respond, everyone has different habits when it comes to email, and people inevitably mix up 10 different topics into one thread that goes on for weeks. You need a system that allows you to create a task, assign it to someone, and have running commentary on the same page.

The best place to do that is in a dedicated issue tracker, maybe a project management tool, and a good chat system if you’re working with other people.

Issue Tracking

The issue trackers I’ve used and liked are GitHub Issues and Lighthouse. What I like about both of them is that they’re both extremely simple, reasonably freeform, and let you enter enough detail into your ticket to explain what’s going on. Some people like other tools, and that’s fine too, these are what’s worked for me. As a general rule if something gets very complicated I’ll stop wanting to use it.

Both of these will integrate with your source control repo, let you tag issues with whatever you want, create milestones (v1.0, v1.1, etc), comment on existing issues, and assign them to team members. Speaking of teams — you should be using an issue tracker even if you’re just one person. Apps like OmniFocus are great for runway level tasks, but bugs and enhancements are usually more than just a task, and you want to be able to get an idea of how they connect.

What’s great about GitHub Issues is that it’s free if you’re all ready using GitHub, and it does most of what you want. What’s better about Lighthouse is that it does everything Issues does, but a project in Lighthouse isn’t tied to a specific GitHub repo. You can’t have Issues without a repo, so if you have a project with more than one repo (e.g., web backend and iOS app), there’s no way to track things across the two.

I’d recommend giving GitHub a try until you feel yourself bumping up against the walls, and then try Lighthouse.

Project Management Tools

Project management tool like Basecamp or Asana can work well when you have a team and you need a 10,000 foot view of what you’re working on. For individuals or even small teams, I don’t think you always need one. For one person writing their own apps, I’ve only seen these used for procrastination and the kind of task shuffling that distracts people from actually making their thing.

On the size teams that I usually work with, I’ve rarely felt a dedicated project management helped up get anything done faster. Maybe for non-technical project managers, but those people are usually a net negative as well1. I imagine when a team gets to a certain size you need something like this, I just don’t generally work on teams of that size, so I don’t know.

In my experience a good issue tracker can take the place of a dedicated project management app, but not the other way around. The reason is that project management tools usually have a concept of tasks, but usually don’t have the right fields to put in all of the detail you need when tracking new features and bugs.

Group Chat

If you’re working with a team, you should have a persistent chat system. I’ve used Flowdock, HipChat and Campfire. Hipchat has the best native apps, but I prefer Flowdock because it was the easiest to integrate with other things like GitHub, was the hardest to lose track of things in and has the least ridiculous annoyances and limitations.

  1. Project managers who understand design and development, or at least stay out of everyones butt can be a different story. 

Turn Off Text Antialiasing in Xcode

I’m not sure in what way my brain is broken to cause this to bother me so much, but I’ve often found myself staring at Xcode after a long time, fixating on the antialiased text being hard to read. I’m pretty sure a retina display would solve the problem, but that isn’t an option for my iMac or MacBook Air. Instead, what you can do is pick a font which has bitmap versions included for small sizes1 and type this into Terminal:

Restart Xcode and the slightly fuzzy antialiased text will be replaced with slightly pixelated non-antialiased text.

  1. I like Anonymous Pro, which has bitmaps for up to 13pt. 

Handling Colors Better in Your Apps

When I’m working on an app something that I try to avoid is to have lines of code like this mixed in my display code:

Instead, I create a category on UIColor — called something like UIColor(MyAppColors) — and add a class method whenever I need to use a new color to the app. That makes the line above something more like:

The main reason I do this is that if I ever want to tweak a color which gets reused in multiple places, I only need to change the category method for it to be updated everywhere. It’s a good practice to avoid having literal strings and numbers strewn throughout your code, and this is a good example of why.

Brent’s Vesper Sync Diary

Brent Simmons has been writing a series of blog posts to journal how he’s been approaching sync in Vesper, and I strongly recommend reading it. Brent’s ability to think through an entire problem is something I constantly work to improve in myself. It’s the thing that really separates great developers and designers from everyone else who starts by typing, and defers thinking until something blows up.

Here’s the posts he’s published so far:

  1. Syncing Tags
  2. Core Data
  3. Immutability, Deleting, and Calculated Properties
  4. In Another Country
  5. Sync Tokens and Efficiency
  6. Merging Notes

UIManagedDocument for Core Data Apps

As someone who’s spent a lot of my career being the “Core Data guy” on many projects, I’m a bit embarrassed to admit I hadn’t taken much of a look at UIManagedDocument until now. UIManagedDocument came around with iOS 5, and I think because it seemed vaguely iCloud related (it’s not), and because none of the apps I was writing were document based (they don’t have to be), I never gave it a second thought. Now that I have, I can’t see any compelling reason to not use it for all of the apps I’m writing.

The best way to think of UIManagedDocument is as a replacement for the “Core Data Stack” class I’ve seen people write in a lot of different projects. What that class usually does is encapsulate set up of a Core Data stack into one class (NSManagedObjectContext, NSManagedObjectModel, and NSPersistentStoreCoordinator), often times with a private queue parent context for background saving. Doing this can make it as easy to set up a new stack as passing a file path and persistent store options to your class. What UIManagedDocument does is exactly everything I just said, and so it saves you having to write a bunch of boiler plate code — which is nice. Creating a new document just involves calling -[UIManagedDocument initWithFileURL:] and setting whatever persistent store options you like. You can now pass the document around as needed, or just use its managedObjectContext property to grab its context and inject that wherever you like.

But what if your app doesn’t work with documents in a way where having multiple persistent stores makes sense? Just create one document with a filename defined in your app. One good use case for using multiple documents is in an app where multiple accounts are allowed. If each account is its own document, than logging out just means deleting the file for that account. Also, since UIManagedDocument is easy to subclass, if you had an app that allows login from different services, it wouldn’t be a terrible place to put syncing logic that applies just to that service. If you were writing an app where you want to save the users data and sync through Service A, Service B or iCloud, you could write different document types to handle some specific differences for the two services and one that you place into an iCloud container.

I haven’t been using the class long enough to say that I’m sure I won’t run into any show stopping problems, but since the API is simple enough that they haven’t jumped out at me yet I’m only seeing upsides to using it right now.

FCModel and Current Thoughts on Core Data

Marco Arment’s Core Data alternative that sits on top of SQLite and FMDB is on GitHub and looks excellent. Core Data has generally worked well enough for me, but maybe not so well that I’m not interested in alternatives. What he’s done is make something simple with a couple of great features built-in:

  • Multi-threading support: Database operations happen concurrently via a serial queue, so you shouldn’t stomp all over yourself. I assume if you’re accessing your model objects in your own threads the normal rules apply.
  • Active record style access: You only need to worry about talking to your model objects and classes, which is simpler in most cases than the way Core Data does it.
  • Simple schema migration: You can version your database and then receive a callback to update your schema as needed.

The whole thing is pretty similar to what Brent Simmons describes in his article about using SQLite instead of Core Data. Brent raises a couple of reasons for wanting to do something a bit different in his article. Mostly it comes down to hitting performance walls and wanting something that’s just a bit simpler and less general. The truth is that because Core Data is a general solution which completely abstracts you away from the idea of using a database, I’m not sure there’s anyway that it couldn’t be a bit complex in places and that there wouldn’t be walls to bump up against. In my experience with Core Data everything works great except when it doesn’t, and because you’re so abstracted away from the implementation detail of it using a SQLite store, when you do hit those walls, you hit them hard. Some things I’ve run up against with Core Data are:

  1. Threading still sucks, even if it has gotten better.
  2. Tries to solve for edge cases I’m not sure anyone has and is overly complex because of it.
  3. Having to pass around an NSManagedObjectContext to do just about anything.
  4. When you have problems, it’s not always easy to find documentation that explains what’s going on.

All of that being said, I still think that Core Data does do a lot for you. The first three issues I raise are mostly mitigated by having good code hygiene and also by using MagicalRecord. Taking the time to read the documentation and also Marcus Zarra’s book on the topic (before you start using MagicalRecord), would probably solve a lot of problems for people as well.

As far as performance goes, it wasn’t easy to get there, but Pinbook imports bookmark collections in the range of 20,000+ in a few seconds on an iPhone 4S, so it is possible to get very high performance when using Core Data. I can’t imagine there’s too many iOS apps out there that have those kinds of performance requirements.

There’s also some specific things that Core Data really makes a lot easier. For example, it’s batching and faulting mechanisms work really well. One thing that I did not have to think about very much when developing an app that might need to display 50,000 items in a table view was managing memory for those items. I’m sure I could have come up with a way to handle that using a custom solution, and it wouldn’t have even been that hard, but with Core Data it was practically free. I’m also hearing from friends that Core Data sync might be finally working the way it should in iOS 7, and if that’s true, and I write an app which really just needs to make sure a users data remains in place between iPhone, iPad and Mac versions, would be awesome, although I’m not holding my breath until I have time to play with it myself.

No general solution will ever be perfect fit for every case. In those cases writing a custom solution is nothing to fear. If you’re writing a Mac or iOS app, however, Core Data probably is the right fit most of the time, and you should really consider what you’re doing when it’s not.

360iDev September 8-11 in Lone Tree Colorado

I'm excited to be given the opportunity to speak at 360iDev again in 2013. As usual, it's a great lineup this year, and there's a few talks this year that I'm really excited about. In particular Brent's SQLite and Justin's Core Image talk are two that I'll definitely be at. I'll be closing out the first day with a general session talk called App Making for Deadites about what Ash's journey in The Evil Dead movies can teach us about making great apps 1. I'll also be on a panel with my friends Matthew Henderson and Samuel Goodwin in the same room Tuesday morning.

360iDev will be held in Lone Tree Colorado September 8-11, 2013. You can buy your ticket now, or check out the schedule.

  1. I'm really hoping that I haven't grossly overestimated how many people have seen those movies. 

Nicer Segue Preparation With Storyboards

When we started developing the iOS app for Braid, a decision I made early on was to use Storyboards. If you’re not familiar, storyboards are a way to create iOS user interfaces visually and draw connections between the different screens in your app. In storyboard-speak, each screen is referred to as a “scene,” and the transitions between each scene is called a “segue.” Storyboards are a fantastic feature for a couple of reasons, including that when using storyboards you can set up static and dynamic table views visually, drag and drop container view controllers and get a visual picture of what you’re entire app looks like.

One part of coding with storyboards has always bothered me though — the strange way that Apple’s example code shows how to set up a view controller before a transition (setting a delegate, detail object, etc):

The string comparison felt a little gross to me, and if you have a lot of different segues, the if/else in this method could get long pretty fast, even if you’re breaking out what happens in each condition into it’s own method. If you do end up writing a method for each segue, all of those -[prepareForSomethingWithSegue:sender] methods could get repetitive pretty fast.

A nicer way is to use a block for each segue you need to prepare and to encapsulate that into it’s own class, which I did. The class is called BRLSeguePreparationController and makes it very simple to deal with preparing for segue’s in this way.

  1. Create a BRLSeguePreparationBlock for each segue you need to prepare for.
  2. Set them using -[BRLSegueController setPreparationBlock:forSegueIdentifier:]
  3. Call -[BRLSeguePreparationController prepareSegue:identifier:] from your view controllers prepareForSegue:sender: method.

Here’s an example:

I’ve given the class it’s own GitHub repo and an MIT license, so use it in your own projects. If you make any improvements, make sure you add a pull request on GitHub. If you find the class useful, please check out my companies website to find out what we’re working on, and download our Passbook pass from there to keep up to date when our app comes out.

Jumping to Protocol Definitions With Pragma Mark

Using pragma marks to organize source files is one sign that the person who wrote the class put a little bit of care into what they’re doing, but they can actually be more useful than just a way of breaking up an implementation file.

My favorite trick is to use how I name my pragmas to jump to protocol definitions more quickly. I always use a pragma mark before the implementation of a protocol in my source, and in most of the code I’ve other people write, they do something like this:

A better way is to use the actual name of the protocol you’re implementing instead, like this:

Now, if you command+click on that Xcode will jump right to the protocol definition, and option+double-click will take you straight to it’s documentation.