iOS App Architecture, Part 1: Setting up

This will be subjective look at creating iOS app, first part will focus on basics like project setup, folder structure, version control and some quality metrics.

Project setup

I usually start with empty project, then I use my crafter gem to apply some default scripts and settings.

Settings

  1. Copy release configuration as Adhoc
  2. Set debug configuration to use
  • DWARF without DSYM, unnecessary for debug and makes compilation faster
  • Build Active Architecture Only - faster for debug
  1. Enable lots of extra warnings, along with code analysis.
  2. Add my favourite pods

Scripts

There is a set of scripts that I always use.

KEYWORDS="TODO:|FIXME:|\?\?\?:|\!\!\!:"
find "${SRCROOT}" -name "*.h" -or -name "*.m" -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($KEYWORDS).*\$" | perl -p -e "s/($KEYWORDS)/ warning: \$1/" 
  • Generating warnings when files are longer than N lines.
find "${SRCROOT}" \( -name "*.h" -or -name "*.m" \) -and \( -path "${SRCROOT}/Pods/*" -prune -o -print0 \) | xargs -0 wc -l | awk '$1 > 250 && $2 != "total" {for(i=2;i<NF;i++){printf "%s%s", $i, " "} print $NF ":1: warning: File more than 250 lines (" $1 "), consider refactoring." }'

Most of my project also add other scripts, Foldify does pre-processing and post-processing steps.

Project structure

Let's start with fact that I use CocoaPods for managing dependencies(hate it or love it but @alloy and the team spend lots of their free time to make Cocoapods and you should at least respect that).

Now there are 2 approaches I'd consider for setting up my project structure, whichever one I'd choose I'll make sure that project grouping in Xcode matches the one on disk perfectly.

Classic organisation by role division

This way we have separation between Our Code, Resources and Libs that we might use (sometimes Libs outside Cocoapods are needed).

Pros

  • Clear separation between file roles in project.
  • All our code is under Classes folder, which makes it easy to run scripts and advanced code analyses (More on this later in the series).

Cons

  • If you'd like to move part of the code to other project, is very likely you'll need to go to move some Resources along with it.
  • Keeping resources properly organised requires more work.

Composition / Modular approach

Other option would be to store code and resources together and group by Features / Modules. eg. if you are working on a widget based app that could make a lot of sense.

Pros

  • Easy to keep resources and code organised
  • Forces you think how to implement code so that it avoids dependency
  • Very simple to reuse module in different project

Cons

  • Resources and code will be close together, so no separation between roles of files

Which one to choose?

I like to think I'm a pragmatic programmer, I've used both approaches and believe it depends on the project and the architecture decision you'll be making. #1 is more popular in general iOS apps, #2 makes a lot of sense for flexible architectures / frameworks etc.

Try both and make a conscious choice for yourself, maybe hybrid approach makes more sense, Core of the app #1 and some modular part (Widgets?) as #2.

Source control, Code Reviews & branching strategy

I've completely moved to git as dvcs, I even use it for important personal documents. Used mercurial before and it wasn't bad, but most companies use git and I decided it's more useful to master one, especially since git is more powerful.

To make sure code quality is high my teams always use Code Reviews, depending on the size of the project team I'd say at least 2 reviewers have to accept changes. To be able to employ Code Reviews, one have to use proper branching strategy. I've tried few approaches and my favourite one is git-flow, it works very well in big and small teams.

More quality please

Other techniques I use to make sure quality is good and project can have a long lifetime are:

BDD

I like to use Kiwi When writing tests you'll probably need to simulate web-services, we don't want to do real requests because tests should give us immediate feedback, I use OHHTTPStubs to make that happen

You can also add acceptance tests with something like KIF, Frank or Calabash. Calabash has advantage as it's multi-platform and backed by Xamarin.

Pair Programming

This is great technique for solving hard problems and working on the most important parts of your app, there is no point in pairing on UI layout, but when writing core architecture modules in your app there is a HUGE benefit from pairing.

It's like live code review, only you learn more from each other, and it doesn't matter what level you are. Senior can still learn something new from Junior.

If you are working remotely, like I'm currently, you can still do pair programming with services like Screenhero.

Composition

Whatever architecture choice I'll select in next part of this series, I'll defienietly use composition, because it's great pattern, it leads to cleaner code, smaller classes, makes it easier to test code and write it with DRY && SRP principles in mind.

Up next

In next part of this series, we'll look at Model Layer and parsing, (probably) the most important layer in your app.

You've successfully subscribed to Krzysztof Zabłocki
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.