Episode #63

From Scratch

15 minutes
Published on April 18, 2013

This video is only available to subscribers. Get access to this video and 555 others.

In this episode I go over how I typically start new projects. I start off when an empty app template, do a bit of organization with groups to keep things tidy, introduce CocoaPods and a workspace, and wrap it up by setting up a map view controller using Storyboards on both the iPhone and the iPad. This project will be handy to use as a base for future episodes.

Episode Links

Project Organizational Structure

  • Lib - a place to store code that is isolated from this project. Typically this is code that I'd eventually extract into a library or pod so it can be used elsewhere. No WAR* classes would go in here because it needs to not have any dependencies on the rest of the app.
  • WhatsAround/Support - Category methods, macros, and other supporting code that doesn't have another home
  • WhatsAround/API - Typically API clients and other networking code will go here
  • WhatsAround/Models - Data models, entities, core business logic. It doesn't matter if it's a CoreData entity or just a plain object, if it's core logic it goes here.
  • WhatsAround/Controllers - View Controllers go here.
  • WhatsAround/Views - Custom views and table view cells go here
  • WhatsAround - App delegate, storyboards, and other top level classes
  • WhatsAroundTests - All tests & test support code
  • Resources/Images
  • Resources/Icons
  • Resources/Fonts
  • Resources/Sounds

This isn't an exhaustive list. I try to keep things in a reasonable structure that is easy to understand & navigate. Occasionally I'll create a new folder to hold things when it makes sense.

Choosing which storyboard to load

If you set a Main Storyboard in the project settings, you don't have to create a window in your app delegate. This is a quick way of loading the correct storyboard depending on if you're running on the iPad or iPhone.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    UIStoryboard *appropriateStoryboard = [self storyboard];
    self.window.rootViewController = [appropriateStoryboard instantiateInitialViewController];
    return YES;

- (UIStoryboard *)storyboard {
    NSString *storyboardName = @"Storyboard";
    if ([self isPad]) {
        storyboardName = [storyboardName stringByAppendingString:@"_Pad"];
    return [UIStoryboard storyboardWithName:storyboardName bundle:nil];

- (BOOL)isPad {
    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);