Ultimate Tag 2.0 is out now Feb 18

Ultimate Tag is hilarious multiplayer tag for your iPad! Grab up to four of your friends and family for this action packed take on an age-old game.

Ultimate Tag Screenshot

Ultimate Tag is a game I've been working on over the last 10 months. Originally released as a proof of concept in 2011, the first version of the product acheived surprising success at roughly 500k downloads. Now it's been completely rewritten. Focused on the top feedback from players, I have added more maps and a much improved controller setup.

Ultimate Tag Reviews Screenshot

Checkout the website for details. You can download the game here!

My Beginning Years Mar 27

For throwback Thursday I've decided to take a look at the beginning of my software development career. Going all the way back to the start, when I was 14, I became interested in learning how video games were made. I found a company called Yoyo Games who published a product called Game Maker. The product has completely changed since I used it, but back then it was a simple game designer with its own drag and drop visual programming language. In addition, they provided an online community where developers could share and rate their creations. To make a long story short, Game Maker excited me and motivated me to create an impressive game to share on the site. So I studied and practiced and studied and practiced. I even convinced a neighbor kid to be my designer and tester. In fact, I still have our some of our "branding":

Collision Gaming Logo

One of my first projects was a top-down mini-golf game for a "one button golf" challenge that Yoyo Games held. I never built enough levels to be content with publishing it, so it stayed as a pet project. A year or so later, I became fascinated with the Guitar Hero games that were taking off at that time. I decided to build my own version: Guitar Villain. Unfortunately, I don't have any screenshots, but I dug up some of the "concept art": (my favorite part is the substitution of "death list" for "setlist")

Guitar Villain Art

So at 15, I set off to build a guitar hero clone... and I did. It was fully featured, including hammer-ons, pull-offs, a star power meter, and star power. I even build a separate visual song builder using my own file format, .gv (which even had its own icon file). It was awesome. My buddy and I loved it. He went all through the forums building excitement and promoting the game, but I never released it. I was never happy enough with the design and I didn't have enough songs...

Fast forward to 2010. I was 16 and taking an AP Physics class at my school. Also I had recently purchased an iPod touch and was becoming interested in mobile applications. Over the past year I had branched out of drag and drop programming and was moving into real languages (higher level ones: php, python, and javascript). I found an iOS engine, scriptable in javascript called Titanium and was playing with it in my free time. A few weeks into the school year, my Physics teacher was teaching us about significant figures (a math concept used in science to determine how precise calculations can be). I picked up the concept pretty quickly, but I remember her mentioning how it had often tripped up students - sometimes taking the whole year to master. I considered that maybe if I had picked it up quickly, I could show others how to as well. It was then that the stars aligned in my mind, and I realized I could build an instructional app for my iPod and share it with the world.

I developed my own curriculum and a cheatsheet for learning significant figures and then began to build out an application around them. The goal was to build something like a swiss army knife for tackling significant figures. In addition to the learning materials, I created a specialized calculator and a group of quizzes.

(In the first problem of the first quiz, I actually embedded the numbers that, if typed into a cell phone, would make up my high school sweetheart's name. To this day, I haven't told anyone. That girl later became my wife :)

In September of 2010, I completed my app and prepared it for the app store. Significant Figures Toolbox was launched into the world. It was the first product I ever shipped. My friends downloaded it and reviewed it to help me gain visibility. Another one of my teachers became interested when I shared it with him after math class. He immediately bought it and wrote a fake review about how it had revolutionized his teaching of special needs students. Interesting, but I took what I could get ;)

Significant Figures Screenshot

For something I made in high school, it has done pretty well over the years. It brought in a little over 2k and ultimately helped in some of my earlier job applications. Everything has its time though, and I've decided to remove it from the app store as I post this farewell. It hasn't been updated in years (that last I updated it was for iOS 4.2). The demand for it seems to have fallen to none. I'm cleaning up my portfolio of pet projects for a new one that is coming soon...

Since my first app, I've focused mainly on mobile software development. My next personal project was an iPad game, which I published about a year afterwards. It's still doing great - downloaded over 200k times and on the top of the charts several times. I've learned a lot since then. Eventually I plan on replacing it with a new version.

The rest, as they say, is history. I later went on to start an internship with a game development company. Since then I've been a part of shipping multiple mobile applications, but the first one was special. It sparked an excitement in me. Software is magical.

Goodbye SFT. You were a good first project :) Thanks for the career and passion.

Rest Authentication With Amazon S3 Mar 14

Recently I have been working on implementing amazon s3 authentication on a client's mobile project. The environment is such that I have very limited access to open source libraries for these types of things. Fortunately I do have fairly standard http request and cryptography apis available to me. With amazon's docs and some code samples I found online, I set to work.

The gist of the security is that for every request, I can package up a set of known data into an agreed upon format (amazon prefers to call this canonicalization). I then sign that string of data with the private key that amazon has given me. I send that as a header along with the original data and my public key in a request for a file. Note: There is a variation that supports the auth in a query string.

Amazon can take the data and put it into the canonical format as well. Then, using my public key, amazon can look up my private key internally. They then sign their data with the private key. If that matches my header, they return success and my requested file.

This is a fairly common security procedure, but I enjoyed laying out all of the pieces in front of me and then building every part of the puzzle from the ground up.

For my needs, I only needed read access to the files. Here is a brief example of that in pseudocode:

#
# Parameters
#
# param examples taken from aws docs:
# http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html
#
AWSPublicKey = 'AKIAIOSFODNN7EXAMPLE'
AWSPrivateKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
httpVerb = 'GET'
timestamp = 'Tue, 27 Mar 2007 19:36:42 +0000'
bucket = 'johnsmith'
objectPath = 'photos/puppy.jpg'

#
# Headers
#
headers = {}

# Date
headers.Date = timestamp

# Resource
resourceString = '/' + bucket + '/' + objectPath

# Canonicalize
canonicalized = httpVerb + "\n"      # method
canonicalized += "\n"                # content checksum (empty because we are reading data)
canonicalized += "\n"                # content type (empty because we are reading data)
canonicalized += headers.Date + "\n" # timestamp
canonicalized += resourceString      # resource

# Sign and encode
signed = base64(hmac_sha1(canonicalized, AWSPrivateKey))

# Authorization
headers.Authorization = 'AWS ' + AWSPublicKey + ':' + signed

# result: Authorization: AWS AKIAIOSFODNN7EXAMPLE:bWq2s1WEIj+Ydj0vQ697zp+IXMU=

Standing Firm Feb 20

It's been over a year since I last wrote any content for this site. It hasn't been for lack of opportunity or topics. It is not that I need more motivation. I have long desired to establish a better journal of my journey as a software developer. I admire many famous developers and entrepreneurs who write about their lives online. That's someone I want to be. I want to be able to share what I'm doing and inspire others. I'd like to be able to look back and see how far I've come.

So what is holding me back? Fear. Fear that what I write isn't going to be good enough. Fear that I won't represent the person I want to look like. There have been times that I take down the content that I've created because I don't like it a week later. I second guess myself.

Who are these people who maintain open source projects and their websites and their products and manage to tweet tens of times a day? Why can't I do all of those things?

I've realized that I need to ask myself why I want all of that. What is a web presence to me? What does it matter if I tweet all day or write inspiring blog posts? The truth is, it doesn't. Those people have cool content because they make cool stuff and have practiced sharing about it. They haven't just materialized into the "cool developer guy" either. Those people work hard and ship things, and that is what is important. They are passionate, and over time they have figured out how to share those passions. That's why people are drawn to following their cool stuff. People are drawn to passion.

Don't get me wrong, I'm not seeking fame. I just want to be a guy that does cool stuff and inspires people to do cool stuff. That being said, I'm going about it wrong. I'm focusing on the illusion of "coolness" and ignoring the fact that I'm not doing enough cool things. I'm certainly not sharing about them enough.

I'm caught up in trying to get everything figured out. In my mind, once I achieve a level of writing ability and "coolness", I'll be ready to share with the world. That's ridiculous. I need to do two things 1) make cool stuff and 2) write about it.

I don't need to delete my posts either. I have been listening to the back to work podcast lately. In an old episode, Merlin mentions how much he hates the titles of some of his old posts. I realized then that even a famous productivity guru is unhappy with his old thoughts and content. Granted, he talked about changing the titles, but the point is that he was unhappy. However, he didn't delete the posts. He was firm in who he was. He knew his own identity as a writer and he didn't need to hide it. I think that cataloging the process is much more inspiring than thinking he just instantly came to be a cool internet guru guy.

That's what I need to do. I need to start somewhere. I need to just be me. I don't need to be someone else. If people like what I do and say, that's great! If not, that's fine. What is important is that I am content with who I am. I don't have everything figured out, but that doesn't mean I don't have something to offer. I'm leaps and bounds a better programmer than when I wrote my last blog post. Someday, I'll be even better. I'd love to have a record of the journey.

Use enum to keep track of UITableView sections Oct 23

I found an awesome tip at NSScreencast this week. Watch the video "Class Introspection" here.

Define an enum like so:

enum {
    SomeViewControllerFeaturedTableViewSection = 0,
    SomeViewControllerMainTableViewSection,
    ...
    SomeViewControllerTableViewSectionCount
}

Ben from NSScreencast points out that the last value becomes a natural section count. So you can easily do:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return SomeViewControllerTableViewSectionCount;
}

And in the other delegate methods, something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == SomeViewControllerFeaturedTableViewSection) {
        // make and configure a "featured" cell
        return cell;
    }

    if (indexPath.section == SomeViewControllerMainTableViewSection) {
        // make and configure a "main" cell
        return cell;
    }

    ...
}

Now you can simply move around the enum values to temporarily enable or disable sections:

enum {
    SomeViewControllerFeaturedTableViewSection = 0,
    SomeViewControllerTableViewSectionCount, // 1
    SomeViewControllerMainTableViewSection, // 2 (because the count is 1, this will never appear)
}

I really like this trick and plan on using it often. Thanks again to NSScreencast for the idea.

How to rename an Xcode 4 project and the root source folder Sep 18

Renaming an Xcode project is not overly difficult, but it does require a few steps. I have been successful with this method:

  • In the Navigator, click on the top-level project element.
  • Hover over the project's name with the mouse and press enter.
  • In the text field, rename the project and accept Xcode's prompts.
  • Close Xcode.
  • Rename the source folder.
  • Right-click on the '.xcodeproj' file and "Show Package Contents".
  • Open the '.pbxproj' file in a text editor and replace all instances of the old project name with the new one.

If everything was done properly, the project can be opened again like normal.

Note to self: option double click in xcode will bring up the full help view Sep 10

When hovering over a method or a class or... really anything in Xcode, option-clicking will bring up a quick help menu. This is useful, but a lot of times I would rather read the full documentation. That's where option-double-clicking comes in. It opens the full documentation and jumps right to the item in question.

Stanford's definition of strong vs weak Sep 10

This was useful to me, so I am making note of it. From Stanford's iOS course on iTunes U.

strong vs weak

  • strong "keep this in the heap until I don't point to it anymore"
    • I won't point to it anymore if I set my pointer to it to nil.
    • Or if I myself am removed from the heap because no one strongly points to me!
  • weak "keep this as long as someone else points to it strongly"
    • If it gets thrown out of the heap, set my pointer to it to nil automatically (if user on IOS 5 only).

Note to self: an object's getter is one of the best places to initialize it for the first time Sep 5

Stanford's free iOS course is a great tool. The video I watched today recommended lazy instantiation of objects.

Example:

- (NSMutableArray *)values
{
    if (_values == nil) _values = [[NSMutableArray alloc] init];
    return _values;
}

A blog Aug 22

Well... I decided to start blogging again. This website will be the home of any content I decide to create for the foreseeable future. I better get busy.