Band App Diary #3: More Thoughts on the Feed

Continued from this post.

My first thought is that it seems like I should be able to generate an RSS feed pretty easily. Maybe I should be looking to what gets RSS feeds contain as guidance for what I return from the feed endpoint.

My second thought is that a completely different approach would be to — instead of returning an array with a bunch of feed item dictionaries created on the server — return a JSON dictionary containing arrays for each item type (songs, shows, videos) and have the logic to display and sort them in the client. That would certainly make the server code simpler. The client could have a sync object that posts a notification when it starts and stops, and then I’d just do a Core Data fetch of all the different types and mash them together into an NSArray in the feed controller.

I’ll still keep it as one API endpoint (instead of calling shows, then songs, etc) since Azure charges me something per API call, it’s the same number of database calls, and it’s easier for dealing with when sync starts and ends on the client.

The reason this appeals to me is that I fear each of the different item types will end up being different enough that I won’t really save that much code on the client by trying to normalize feed items on the server. It feels like it could become kind of restrictive later. It should also make caching easier since it means I can have a one to one match between my server and client data model instead of needing the sort of imaginary “feed item” objects. The last benefit I can think of is that it saves me from having to make another API call every time I want to show a detail item.

The downside is that the RSS feed now would be extra code if I wanted to do that. Not much extra code though, and I was only really thinking of doing it because it seemed like kind of a freebie.

I think I’ll do this unless someone gives me a good reason why I shouldn’t.

Band App Diary #2: Database to Feed List

Since I’ve decided on going with a single feed list that’s going to represent all of the different kinds of band content that might get produced, I’ve been thinking about how to represent that in a database and how I’m going to generate the JSON the iOS app needs. I’m using a database instead of something like MongoDB because I understand databases fairly well, and because I’ve decided to use Azure Mobile Services for the server, and using MSSQL is the most straight forward option for that. I think I could probably get by deploying and hosting the app myself somewhere else, and for a future project I might do that, but the way I’m viewing Mobile Services is as a really nice front end for creating a Node app where I don’t have to think about server stuff at all. At this point it’s better if I can just focus on writing code.

So, getting back to the database, some of the things I need to represent are:

  • Shows
  • Songs
  • Videos
  • Social
    • Instagram
    • Twitter
    • Facebook

There’s probably more I’m forgetting, but that’s a pretty good start. The first way that I thought to represent all of the different feed item types was to have a big items table that would have the information for a feed item with an type ID, but that doesn’t work, because each of these things could actually be significantly different (a show song won’t have a lat/lon or venue name, but a show will).

The shows and songs tables might be have some columns like this:

  • Shows
    • unique_id
    • venue_name
    • lat
    • lon
    • date_time
    • duration
    • city
    • description
  • Songs
    • unique_id
    • media_url
    • title
    • description
    • post_date

I’m leaving some things out, but they aren’t really critical right now for what I’m trying to get at. What I want to do is get all of the different feed item types and serve them up as JSON via one API endpoint to my iOS app. In order to keep things simple, I think the best way to do that is to when the endpoint is called fetch each of my feed item types, loop through each and create an object for each with the information that’s needed to display them in the feed, add them all to an array and return that. The properties could be things like:

  • unique_id
  • title
  • description
  • thumbnail
  • type (integer value to differentiate each item type)

I could then use the type and unique ID to do things like call a “show with ID” endpoint to display a detail item. I’m almost certain that this is not the most efficient way to do this, but also that if I need to optimize it later, I should be able to do so in a way that doesn’t change anything for the client. The reason I’d like to represent each type as being the same in the feed JSON is that it makes it possible to keep the client code a lot simpler. I’m not sure if that’s the right call or not. Maybe someone with more experience can tell me if I’m way out in the weeds here.

Update 7:39 pm: I had more thoughts about this approach being a good idea or not.

Band App Diary #1: Initial Design Thoughts

If you read this blog lately, you know that I have (am) a band called Fisherman’s Porch, and that I’ve been making music for a long time. One idea I’ve had for a while has been to somehow combine my app making and music skills in an interesting way. I’ve also wanted a reason to do something with development that would give me some real world experience writing server side code. I’m going to follow Brent’s footsteps and put all of my design and code thoughts out there, so that hopefully I can learn something from the feedback I get.

The other day when I posted on Twitter that I was trying to think of a side project I could use Microsoft’s Azure Mobile Services to write a backend for and Nick Harris responded with this:

@collindonnell write an app for your music with a blog like feature talking about the songs.

This seems like the perfect project to try this out on for a few reasons:

  • There aren’t thousands of Fisherman’s Porch fans out there (yet!), and it’s not going to be storing a bunch of peoples important personal data, so I can experiment as much as I like with the design and backend architecture.
  • It’s not an idea anyone can “steal,” so I don’t have to be secretive at all about creating it and blog about the whole process.

An App Worth Downloading

I don’t want to make an app that’s just a static advertisement for my music, because no one will download it, and if they do, they won’t keep it. Plus, designing an app like that just isn’t as interesting to me. I want to use this to stretch my design muscles and see what I’m capable of. Ultimately, the hope is that the app could somehow get people who would have otherwise never ever heard of Fisherman’s Porch to become interested, and people who are interested to stay that way. If you think about how stupid most apps that are created to advertise different brands and whatnot actually are, it’s a pretty big goal.

So, I think it’s got to do a few of things to have a chance at achieving that. First, the content can’t suck. If my music and other things I put into it are lame, it doesn’t matter what I do. I’m going to take it as read that my content can’t suck. Good content alone is going to be enough though. There’s tons of bands with good songs no one cares about.

The second thing is that it’s got to be fun to touch and look at. The UI has to be great. It can’t look like a list of songs in the Music app. For the kind of apps I’ve created in the past (productivity mostly), I’ve gotten a lot of mileage out of “what would Mail/Contacts/Music do?” as a starting place. If I were a famous rockstar, that might fly, but I’m not at all. It has to feel like something special.

The design also needs to look full with the amount of content one person (me) can put out. If I had a table view of six songs, another separate photos view with a few photos, and a videos list with two videos on day one, that’s going to look empty. Instead of a tab bar app with a separate tab for each of those things, or some kind of table view based navigation hierarchy, I’m thinking a single feed that has everything in it. If you want to just listen to my music, you can do that in this app, but the main purpose of this app is to find out what Fisherman’s Porch is up to right now. The types of content I can think of right now are:

  • Music.
  • Videos.
  • Photos.
  • Content from social networks like Twitter, Instagram, etc.
  • Other links to things like blog posts.
  • Shows.

On the technical side whatever I do should also accommodate the possibility of me coming up with new types of content in the future. I don’t know what those are yet, but I guess that’s kind of the point. Out of all of those types of content, shows are the one that I think deserve their own special view. Giving shows their own view gives me a nice place to put things like getting a push notification if I’m playing a show nearby or requesting a show in your area. Requesting a show could be as simple as a single button. I’d store the location on my server and if I see a bunch in one general area, I can find out about booking a show there at some point.

Inside of the feed list, I think it would also be nice if people could comment on items that show up there. Review a show, give feedback on a song, that sort of thing. Of course this is the perfect place for trolls to tell me that I “totally suck, lol,” so I think before someone can leave a comment I’d ask them to authenticate with either Twitter or Facebook to remove some of the anonymity. If there’s a way to do it without being a total tool, it might be cool if I could use that as a chance to ask them to like/follow Fisherman’s Porch. I’m thinking more like a checkbox which is default off instead of an alert view that pops up in their face after they log in.

Other random things the app could maybe do that might be cool:

  • Notifications for new content. If this is annoying people will just delete the app though, so I might have it somewhere that people have to turn on instead of just on for everything by default.
  • Passbook passes for shows. Maybe.
  • Have some basic analytics so I know which songs get listened to the most or the general geographic region people who listen to my music are in. Nothing creepy, but it would be useful to know if I have a big cluster of fans in one area when I go to book a show there.

I don’t know if all of this will make it into the first version, but I’m kind of excited about this app as a place I can try new things. Since I’m already over a thousand words into this post, I think I’ll take a break and collect my thoughts on what’s all going to need to happen technically.

Dancing With weakSelf

There was a really good post on the Black Pixel blog by Rich Wardwell about the implications of capturing self in Objective-C blocks which Brent Simmon’s posted a response to on his blog. If you’re lost, I’m talking about doing this sort of thing to avoid retain cycles:

__weak MyClass *weakSelf = self;
self.someObject.blockProperty = ^{
    weakSelf.someProperty = something;

Brent’s thoughts/rules for blocks partially mimic my own1. I never use -[NSNotificationCenter addObserverForName:​queue:​usingBlock:]; I just don’t see the benefit. Unlike Brent, it’s not uncommon for me to copy a block and assign it to a property, but usually if I start having more than one or two somethingHandler blocks, creating a delegate protocol is a better fit most of the time (this code also tends to be easier to debug). I also agree that thinking about if self really needs to be used in the block at all is a good practice (Rich also mentions this).

I can’t say why exactly, but whenever I have to the whole weakSelf thing, it feels like I’m doing something wrong — it seems like kind of a code smell. That’s not to say I never do it (I do it all the time), but my general feeling is that if I need to, I should probably think about if I’m approaching this from the right angle.

  1. One difference. At some point recently I realized I’d memorized the crazy block syntax: BOOL(^someBlock)(NSString *string). I’m not too proud of this, since I’m pretty sure it points to some kind of underlying psychological disorder 

Don’t Store Static Content in Code

Sticking large blocks of static content directly in code is a bad idea, but I see it all the time. You keep your image data separate, so why have a 2000 word privacy policy stuck in the code directly? Loading content like this from static text files, as an HTML string into a web view, or keeping configuration data in a property list is a much better choice, and what I do pretty much anytime I can.

If you have code like this in your app, you’re doing it wrong:

self.titleLabel.text = @"Privacy Policy";
self.lineTwoLabel.text = @"Really private. So policy.";
self.paragraphOneLabel.text = @"<600 words of body text>";
self.paragraphTwoLabel.text. = etc...

Instead, if you’re just talking about static text with some styling, you could keep all of that in an HTML document and do something like this:

NSString *privacyPath = [[NSBundle mainBundle] pathForResource:@"lovely_terms_of_use" ofType:@"html"];
NSString *privacyHTML = [NSString stringWithContentsOfFile:privacyPath encoding:NSUTF8StringEncoding error:nil];
[self.webView loadHTMLString:privacyHTML]

Let’s say you had a list of documents like this you needed to display, like terms and conditions and about, which were all listed as rows in a table view. Instead of coding what each row is, you could save a lot of code by putting that information into a property list. If you store the info for each document as an item in array — with keys like title and documentName — you can load that array in your view controller and then pretty much automate this whole process with two classes and a few lines of code.

On top of getting clutter out of your code and saving the amount of code you write, there’s other nice things you can do now too. For example, maybe you want to be able to update any of these documents remotely. All you need to do is check a URL, download a copy of the files into your cache directory, and check for if there’s a match there before you display the one you bundled with the app.

Getting a feel for where you can get static content of out of code and into external resource files lets you not only write better code, but less of it.

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:

defaults write NSFontDefaultScreenFontSubstitutionEnabled -bool YES
defaults write AppleAntiAliasingThreshold 24

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:

view.backgroundColor = [UIColor colorWithRed:0.75f green:0.64f blue:0.64f];

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:

view.backgroundColor = [UIColor alb_defaultBackgroundColor];

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.