The Deep End: What I Learned From My First App Submission

Day 24

I haven’t posted in a while but I have a good excuse! About a week ago I found out about a competition Sensis Australia were holding for developers to create an application that uses their new API.

Now, at this point I’d only been learning iOS development for about a month or so in my free time; I wasn’t ready for a full blown, public application. Not only that, but in order to get it in the App Store in time I would need to create the app – from start to finish – within a week.

That’s bonkers…but, you know, zombies! I can’t say no to zombies!

And so, after 6 days and about 100 hours of working non-stop – pausing only for Mothers Day on Sunday – I created my first application. I learned more in those 6 days than I had in the entire time I’d been learning iOS. I’m glad I did it, and think I’m ready for round 2 :)

Day 1: Concept, Wireframes & Test API Call

The first day was about planning exactly what I was going to create, and ensure I had the ability to create it. My idea was simple enough:

When the Zombie Apocolypse comes, do you have a plan? This app will allow you to generate an action plan for what to do should the undead rise, using the Sensis API to find nearby business that can help.

For the UI, I was imagining a table view which you could add items to. Tapping on a cell would reveal a detail view including a map and contact details.

The next thing was to get the API working within Xcode. Fortunately there was already a library available for interacting with the API on Github. So I imported the library into my Xcode project and tried to make my first API call.

Looks like the library isn’t ARC based. Now, in my short time with Xcode I’ve come across this a few times; usually it’s just a matter of removing references to release and retain, however I didn’t want to start changing code in the library. Digging through the documentation revealed a handy trick, allowing me to set a compiler flag on individual files.

It’s just a matter of going to Build Phases and setting the compiler flag -fno-objc-arc to any files that aren’t using ARC.

Once that was done, I had liftoff!

Day 2: Custom Table Views

I wanted the table views to look customised rather than the stock iOS designs. Eventually I figured it out, but found it to be quite fiddly. Here’s the final version:

It’s something I need to do a proper tutorial post on, but for now I’ll share the broad strokes for where to look. The general steps for creating a custom table view are:

  • In your storyboard, add a Master Table View Controller and make sure the type is set to Custom, and the style is either Plain or Grouped (I choose grouped).
  • In your prototype cell, manually add whatever elements you want to appear inside each cell (labels, UIViews, etc). This can be done simply by dropping them into the prototype cell.
  • Create a custom subclass for  UITableView and UITableViewCell, then assign those subclasses to your Table View and Table Cell respectively.
  • Create IBOutlets to connect your storyboard objects to your custom UITableViewCell class
  • Now in your Table View Controller, include the custom cell class, and edit your tableView:cellForRowAtIndexPath: method to handle your new class, for example:
  • Likewise, you can customise the look of the table itself by editing the drawRect: method within your custom UITableView class, for example:

That is obviously a super abridged tutorial, but I promise to write up something more substantial a little later!

Day 3: Core Location & MapKit

Core Location and MapKit are also worthy of an entire post and took hours of research and experimentation to get right. I’ll leave them for a separate post when I can explain them properly, but I have a handy bit of code for those working with Core Location. To get the user’s current location you’ll need to do the following:

  • Include the CoreLocation framework in your project.
  • In your controller, include core location in your header
  • Also make sure you set your controller as a CLLocationManagerDelegate
  • Once set up, if you want to find the user’s location you can trigger the location manager’s startUpdatingLocation method like so:
  • Once location has been updated, this will trigger your delegate’s locationManager:didUpdateToLocation:fromLocation method:
It’s also worth adding a locationManager:didFailWithError: method to handle cases when the user’s location can’t be found, or they have turned off location services.

Day 4: Mothers Day & Icons

Mother’s day is all about gifts and over-eating, so I didn’t get a lot of time in Xcode. I did, however, manage to get all the icons done!

Day 5: Cutting Features & Testing

By day 5, it was pretty clear I wasn’t going to be able to implement all the features I wanted in time. I wanted the user to be able to compile their own list, but I ended up just making the survival plan pre-generated. I also wanted to dynamically calculate the user’s chances of survival based on how close each tactical location was to them, but again I needed to cut it if I had any chance to getting the app through the approval process in time.

So I spent all night testing what I had, squashing bugs, adding a help screen, and so on (it’s funny how the last %10 of development always seems to take the longest). By sunrise I had an app ready for submission!

Day 6: App Store Submission

I had everything lined up, I even had a spiffy logo ready to go. I’d never submitted anything to the app store before but the first part made it seem pretty easy. Here’s how it works:

  1. Go to itunesconnect.apple.com
  2. Select Manage Your Applications
  3. Select Add New App and follow instructions
This allows you to enter the various information iTunes needs for the App Store listing. Once that’s done you can head over to Xcode and create the binary. This is done by  choosing Archive from the Product menu.
If all goes well you will be walked through the final steps to submit for approval, but instead I got this:

After some hair pulling (and some help from a work colleague) it turned out I’m an idiot and never set up a Distribution Certificate. In order to create an archive you need to do the following first:

  1. Create a Distribution Certificate from the Developer Centre
  2. In your Project settings, select the distribution certificate for the Code Signing Identity’s Release setting
  3. Next go to Product > Edit Scheme and set the Build Configuration drop down to Release.
  4. Go to Product > Archive and cross your fingers!

Now, it should be said that even if everything is correct and in place that still doesn’t guarantee you’ll have a binary. I’ve heard horror stories from a bunch of devs about infuriating problems creating a binary; some of whom ended up having to create a fresh Xcode project and re-add everything by hand.

It’s a surprisingly unintuitive and error-prone system from a company that is known for its superior user experience. Let’s hope it gets ironed out in the future!

Closing Comments

Creating an iOS app is 6 days when I’m still learning the basics of Objective C was a stressful experience to say the least, but I’m really glad I did it. Learning abstract concepts and creating test applications is one thing, but working towards a clear goal and creating a real product really fast-tracked my development. Regardless of the outcome of the competition itself, this has been a hugely rewarding experience and an important milestone in my growth as an iOS developer.

If there were a zombie apocalypse right now, they’d all be coming for me, because my brain is overflowing with juicy new knowledge. Fortunately for me, there’s now an app for that ;)

  • breakingCode
    Awesome post, and even more awesome app! Love it. It's true that actually going out and making an app exposes all the holes in your knowledge.
    • TomLongo
      Thanks mate! Yeah it's funny how you can be really confident about something in your head, but when it comes to doing it you quickly realise Stack Overflow is your friend ;)