Skip navigation

I guess I’m doing this every two weeks instead of every week!

This last Saturday, I attended YCombinator’s Startup School 2016. Rather than write about that, I’ll talk about it a bit in my next update video. Or I may make two update videos.

I had two major changes over the last few weeks, plus some minor ones.

The Big Refactor

Finally started the not-undoable massive overhaul of the app to support multiple bands. This includes a new band selector screen, different login flow from a user perspective, and changes to the player/user/session systems, order of loading data, and lots more.

The biggest change is that the app goes from knowing it needs all the data about one band right at startup, to having to wait until login to be told what bands are relevant. This also means that I have to plan for much larger data sets to be loaded incrementally – we don’t want to be loading ten thousand venues and a thousand bands at startup if the user only cares about a few bands and their tens of upcoming shows.

I also had to rewrite a bunch of code to be aware that there may not be a “current band” because the user might be in a state where they’re selecting bands.

I left the app in a semi-working state at the end of last week, and I hope to finish this all within the next few days. Refactoring is fun, and/or I’m a masochist.

Upgrading XCode and Swift

Upgraded to XCode 8/Swift 3. Ripping the band-aid off!

One of the major changes is that the compiler is now much more strict about Optionals. I don’t remember the specifics, but the compiler is so helpful about telling you what you’re doing wrong that remembering the specifics isn’t necessary anyway.

There was a non-trivial amount of work because of changes to handling of AnyObject and the addition of the Any type. Basically, I need to cast JSON data that comes back as AnyObject to other formats earlier in the process, and appropriately use the Any type whenever possible. A whole lot of this:

let chats = json["chats"] as [AnyObject]
for chat in chats
{
    self.chats.append(Chat(data: chat as [String:AnyObject]))
}

That cast to [String:AnyObject] didn’t used to be necessary because I could just pass an AnyObject to Chat.init(data:) and read properties from it directly. No more!

I’m okay with this change because it actually makes things much more clear.

I’m also glad that this no longer causes a compiler segfault:

methodName(anyObject["some_property"] as AnyObject)

The minor changes

  • Real-time RSVP updates are now working, including properly removing people from the list if they cancel
  • Set up Redis and Celery to support offline processing of tasks like…
  • Saving shows and marking them as Ready to Promote will now automatically create scheduled push notifications to all fans of a band about the show. Updating the start time will appropriately update the push notes (well, update is charitable… it deletes them all and makes new ones). Big thanks to OneSignal for making this easy.
  • New chats for a given band will trigger push notes for all users who follow that band. This is throttled to every ten minutes so it’s not TOO annoying. (I’ll add some client config to turn this off at some point before full launch.)
  • A bunch of custom Django admin stuff to make sure bands can only edit their own information and shows.
  • Added change tracking for Shows and Venues. I want bands to be able to edit Venues freely, wiki-style. In order for this to work, of course, I need to have past update info available.
  • Created reusable view for lists of fans in tables for RSVP, check-ins, etc.
  • App now handles when no future shows are available instead of crashing
  • Updating HockeyApp settings, tokens, app name, etc.
  • Added a skinning plugin called NUI, played with it a lot, used it to find a good look, and then deleted it because it’s not worth keeping now that I know what I want everything to look like!
  • Making the “beat” interval (how often the client pings the server to get new chats and other updates) configurable via the server
  • Spent a ridiculous amount of time wrestling with Framework config, Cocoapods, etc. This stuff is not that hard, but if you do something wrong and don’t notice, you can end up spending a lot of time fixing your mistakes.
  • Finally fixed a bunch of possible weirdness with saving off device-specific push note ids when a player accepts push notes on a new device or a device that previously had a different account associated with it.

That sounds pretty productive, right? Once the major refactor is completely done and I’ve got a logo ready, it’ll be time for Private Beta. Awesome!