Skip navigation

Category Archives: Startup

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!

 

Hey, it’s my first post on Medium!

Check it out here!

I had planned on doing these “git commit” summaries every week, but I took last Friday off to spend time with my fiancee, so this update’s going to include everything since my last one!

  • You can now take a photo of your pretty face and set it as your profile photo. No support for importing other photos or images (this is deliberate)
  • Adding support for an RSVP system
  • Added a widget that displays RSVPs for upcoming shows and checked-in users for the current show. It updates in basically real time, so profile images will appear as people are checking in or RSVP’ing. Pretty sweet.
  • Initial work towards supporting all bands in one app (rearranged a bunch of stuff on the server)
  • Added a Feedback button with my email address and phone number
  • Added support for when there are no upcoming shows (so the app doesn’t just crash)
  • Shows can now have an optional name and description
  • Integrated MixPanel so I can have analytics
  • A ton of refactoring, new Service classes, stuff like that. I’ll do a technical post about this at some point when it’s more stable.
  • I spent a bunch of time working on build configuration. I learned how to set up multiple builds and created an AppConfig class that used compiler directives to switch config details depending on build flags. I compiled to TestFlight, which is not a great option for beta testing because Apple wants to approve everything. Then I compiled for HockeyApp, which is a lot easier to build for but harder to add new testers because you have to update the provisioning profile for EVERY SINGLE DEVICE. Basically, beta testing on iOS is a pain in the ass no matter what.
  • Also set up a Heroku account… not quite as easy as they make it sound to get an app up and running when it was already configured to work somewhere else!

Not quite as much raw stuff, in terms of app bullet points. Some of that was because I was working on market research and surveys, and some was because stuff like profile photos, RSVP’s, and Heroku setup took up to a day each.

In other news, I’ve been accepted to YCombinator’s Startup School 2016. If I have enough of this app done by then, I may build a special Startup School version and release it before the event.

A bit late on posting this here, but here’s my latest video blog. This time, about “why” I’m doing this, from a more personal perspective.

Posted a new video blog yesterday about validating my idea!

Enjoy!

I quit my job to build an app and start a startup!

It’s been a few weeks and I’ve been posting updates to Facebook, but today I feel like updating my WordPress!

According to my git commits, here’s what I did this week:

  • Check-ins are now associated with shows instead of venues (obvious in retrospect)
  • If there’s a show happening right now, the app will get a list of all checked-in users and flag them when they participate in chat.
  • Users can now change their display name via the Settings/Profile screen
  • Added support for different types of shows (IE regular show, secret show, appearance w/o music, invite-only shows, etc.)
  • Added a leaderboard to the app that fetches on app startup but can be reloaded via pull-down-to-reload pattern
  • App now knows which users are band members so they can be highlighted in chat
  • Refactored all client and server request handling code to use JSON for client requests (previously was url-encoded string, which was working until I needed to send an array!)
  • Added “heartbeat” code that automatically grabs chat and check-in info every ten seconds. It’s generalized so that any frequent updates can be added and broadcast to the rest of the app using a notification pattern.
  • Added support for push notes via OneSignal, including storing push note data on the server so I can support server-side push notes later. (Later meaning tomorrow, when I hope to get them working!)
  • Added client support for loading band info at startup (future support for multiple apps running on the same server)
  • Updated top-bar layout to user prettier (and smaller) font
  • Completely refactored app startup sequence into a service separate from controllers (should have done this in the first place!)

Whew! That’s a lot for one week, but I still had a bunch of other stuff going on (errands, etc.) so I definitely could have done more.

Plus, I wasted a ton of time on push note stuff before implementing OneSignal. I didn’t realize that OneSignal handled the whole PN prompt process from the start!

One thing I want to note that I did last week that I’m really proud of is lazy loading of user info in chat. Basically, I don’t want to send player info along with every chat message because that’s hugely inefficient. Here’s my solution:

  1. Chats from the last week are sent to the client on startup along with player info.
  2. Leaderboard data is always sent on startup, and it includes the top 250 users. It’s safe to assume that these will also be users who chat a lot. Player info from the leaderboard can be used to populate player info in chat.
  3. Chat info loaded from the ‘heartbeat’ (IE after startup) is sent only with player id and message. The client matches up player ids to existing in-memory data, compiles a list of player ids from chat that it doesn’t have data for, and sends that list back to the server to get info for JUST those players.

This guarantees that the client will only ever load player data for new chat participants, and the server doesn’t ever have to send redundant player data along with “heartbeat” chat data.

Whew, that’s it for now! Tomorrow I’ll tackle server-side push notes and then hopefully go see Star Trek Beyond!