A Year in the Trenches- Notes From a Developer on Her App’s 1 Year Anniversary


I have been working in the same code base for a year now- the latest app is El Bingo if you want to check it out. In review, currently, I have Chinese Bingo and an upgrade to our first app, Le Bingueau (free until 9/16!).

I’ve learned some very interesting things working and focusing on one set of functionality. Sure, I’ve done other apps and other projects, with other developers or solo. And that all helped, don’t get me wrong. But coming back to the same acre to plow, you get to know the nooks and crannies very well. In a way, it’s all more focused and interesting. So I thought I’d crystallize these learnings, so I’d remember them better of course, and to share the wealth.

First, basic functionality if you haven’t played the game. Like lots of turn-based board games, you have a board, you have tiles, user (single) selects the tile and it’s wrong or right. There are decks, discard and pull decks, and a “call word” which is the active pulled card from the deck. There’s a point of comparison between what the user has clicked (the tile on the board) and the call word.

We’re doing this in various languages, so sometimes you have a simple “english/foreign language” attribute to a tile, and sometimes there’s three main attributes, English/Foreign/Latinized. For Russian Bingo and Chinese, with different alphabets, we offer a Latinized foreign word.

Visual Design- Guidelines
A UI designer (my boss at day job- thanks Chris!) did a thorough review of El Bingo and helped me big time by introducing the concept of even margins, the vertical and horizontal guidelines in Interface Builder. I programmatically create the game board now, too. The pixel-precision of UI design cannot be understated for mobile app design. I have to do most of my design myself, because it’s so hard to find a good designer, and getting pro tips like that was invaluable. We have a long way to go of course, but I noticed right away the improvement. Any kind of UI/UX advice you can get on your app is very important. You can see our UI progression from the board screenshots, which are kind of interesting, too.

Suppress the Ego
As a developer of this app for a year, I really think I know the shit. Like, The Shit. So I have to remind myself to check the ego almost all the time. I’m a firm believer in Customer Development, and we have contact-us buttons everywhere in the app, and will give promo codes to those that give us feedback- so we end up having long discussions with our customers. The problem is, as the developer, to take the f-ing feedback, and not spend months animating a button (did that). Instead, get working on new boards and levels, and an Android version, which is what they want. I’m lazy- it’s easier to play around with animation- but in reality only the game developers give us that feedback, not the actual customers who paid $1 to download the app and bothered to email me.

Analytics
I’ve implemented Flurry Analytics- and there are others out there too, like MixPanel- to gather usage numbers. I’m using a button to calculate buy level interest before we do the effort, and I’m relying on Flurry to count how many users want this feature. It hasn’t technically passed the Apple Store Review, so we’ll see, but I’ve had another app pass with Flurry, and it’s got a large customer base, so I’m sure it’ll be fine.

In-App Links to Appstore
I’m not doing iAds, but instead linking to our other apps from within the app, on the information page. This came about maybe a few months into our development, and now I’m trying to keep it up to date. I don’t have metrics on this feature and whether it’s working.

Current Challenges
Probably the hardest thing now is to figure out where to go next. I’m relying on popular customer feedback for our two initiatives:
– Android Version
– More boards

And recent feedback from one user:
– Progressive vs. categorized words

The improvements that I’d like to make and/or think are important (though not validated yet by customers)
– German & Japanese
– Native American Languages (Chinook Jargon, the first)


I’ve started to do some interesting sales analysis, and oddly the niche languages are performing better than other languages- Swedish Bingo namely.


Some technical notes….

Arrays vs. Objects
Data structures come and go, but arrays are forever ;) I have used databases -all flavors- and in this app decided to just use XML as the source data structure, and in-app, arrays. The data interaction is relatively minimal and I didn’t want the code of Core Data or other data connection code clogging up my app. At some point, perhaps 4 months ago, I switched to using objects. The pro’s and cons of using arrays vs. objects: I really like the simplicity and clarity of using objects. Also, objective-c seems to perform better. There are all kinds of gotchas with NSMutableArrays, so they’re really not that reliable.

If you don’t know what I mean by objects vs. array, here is an example:

Before, I had something called the “omniarray” which contained arrays of each tile. I’d find the object by the index, which was a position on the board, and update it with “correct/incorrect” depending on the state of game play.

Now, I have an object called the “board” which, when initialized, contains 25 “tile” objects. Each tile has all of the attributes of tiles- the English word, foreign word, latinized word, whether it’s correct, x/y position, etc.

See, it just makes more sense. They both work, one is just cleaner and easier to read- and less code, which means less bugs.

App Delegates
I was trading data between views, down the stack, as the user moved from level to level, seeing win screens, information, and credits. Now, though, I basically do almost all of the inter-app business in the Application Delegate class. It’s so much easier. The delegate sets win levels, upgrades the user, loads data from XML, almost everything. Relying more on the appDelegate as the central repository for app data has made navigating the app more clean.

NSNumber Not Int
During an iPhoneDevCamp, I remember having a long discussion with programming partner Stacie Hibino about the use of native C types like “int” and NS class objects like NSNumber. I use ints within a class’s method, but in a more global context, I use NSNumber.

Sadly, and frustratingly (and various other feelings…) NSNumber is just easier to use in Obj-C and iPhone dev than the native types. In this app, I am passing around quite a bit of NSNumbers, and mostly treating them like ints- [level intValue]- etc. all over the place. You can retain them, they’re a passable property, and while it’s more code and overhead, my world has been easier with this data type than the int. I can’t explain it past that, but sticking to some of the NS class objects works better.

Enumerators
A lot of progress has been made with enumerators in Obj-C, and I’ve used them quite a bit, though there are known bugs with changing values in NSMutableArray as you’re looping through it (totally lame). Mostly I do the “for(tile *t1 in correctArray){ … }” style, and you can waste a lot of hours reading the threads in StackOverflow regarding this. More a reason to avoid them as a basic architectural data structure and go with objects.

Temporary NSMutableArrays
I do this trick quite frequently where I create a temporary NSMutableArray, manipulate it within my method, then assign it back to the global property. There are limitations with NSMutableArrays where you lose data/over-retain. So you can only really do one or two instance methods with them as properties. Hence, create a temporary one you can use all of the methods with “contains object” “add object” etc. and then swap it over to the global property.

Any notes and comments are welcome of course!

We have twitter @bingueau, and a blog- Language Requirement– I really need to update, as well as an email address- bingueau-at-gmail.com.

No Comments »

No comments submitted yet.

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>