Example App: Koober
Written by René Cacheaux
This chapter introduces Koober, the example app used throughout this book. You’ll explore all the screens that comprise the app and how they work together. At the end of this chapter, you’ll take a quick tour of the Xcode project and source code. A reimplementation of Koober accompanies every chapter so you can compare and contrast different architectures. The material in this book assumes that you have a good understanding of the example app, so make sure to read this chapter before diving into any of the following chapters.
Imagine a world in which animals are human-like. They speak different languages, live in different countries, go to Mermaidbucks for coffee and so on. In this animal kingdom, smartphones have just hit the market for the first time. All the developers around the world race to build the next big app.
The kangaroo taxi industry in Australia is prime for disruption. Riders are tired of paying in cash and having to physically walk to the street to hail a kangaroo. Plus, some of the kangaroos have been hopping too high, making their passengers sick. Riders have no way to give feedback. A team of developers in Sydney noticed this and decided to launch a new startup company to build Koober, the next big ride-hailing app.
How Koober works
Koober works just like other ride-hailing apps that you might be familiar with from our own human world. Koober has the common components that make up a modern app such as onboarding, sign up, sign in, account profile, etc. Here’s a quick tour of all the screens, end to end.
You’ll see the launch screen when you first open the app. This screen comes and goes really quickly, so you might not see it. The app is determining if a user is signed in at the time this screen is presented.
If a user is not signed in, the app transitions to the welcome screen.
From the welcome screen, you can navigate to the sign-up screen to create a new user account.
Requesting a ride
Once you’re signed in, you’re taken to the pick-me-up app flow. First, the app determines your current physical location. The location is used as the ride’s pick-up location. Koober’s user location system always returns Sydney, Australia as your current location so you don’t have to give your actual location.
Next, you’re presented with a map that’s annotated with your pick-up location. At the top of the screen, there’s a Where to? button for navigating to the drop-off location picker.
The drop-off location picker is pre-seeded with locations. You can also perform a search using the
Once you pick a drop-off location, you’re taken back to the map screen wherein the drop-off location is annotated and the ride-option picker is presented at the bottom of the screen.
You use the ride-option picker to pick a ride option. A ride option specifies which kind of animal will pick you up. Some animals can carry more riders than others. For example, in Sydney, wallabies, wallaroos and kangaroos want to give rides for Koober.
Wallabies, wallaroos and kangaroos are considered different kinds of kangaroos. The three kinds of kangaroos range from smallest to largest in size, respectively.
This means that wallaroos can cary more weight than wallabies, and they are more expensive to ride.
As soon as you pick a ride option, you can confirm your new ride request. That’s how you request a ride with Koober.
Waiting for pick up
Once your new ride request is sent, the app takes you to the waiting-for-pick-up screen. You can start a new ride request from this screen by pressing the Start New Ride button.
Viewing your profile
You can view your user profile by tapping the Profile button located towards the top right-hand corner of all the pick-me-up flow screens.
You can sign out of the app from the profile screen.
After you sign out, the app presents the welcome screen wherein you can navigate to the sign-in screen. You can always sign in with email@example.com and password.
When planning this book, we wanted to make sure that the example code would be applicable to real projects. We heard from the community that most architecture books oversimplify examples, leaving readers to figure out the real-world application of the theory. So we decided to build an entire app with the complexities of a real app to use as the basis for our examples. We really liked ride hailing because ride-hailing apps have all the complexity of a real-world app without an explosion of screens and UI to build.
Koober demonstrates architectural theory while incorporating aspects such as networking, persistence, authentication and more. We acknowledge this app doesn’t cover all of our readers’ type of projects; nevertheless, we hope everyone finds the material easy to incorporate into all kinds of projects.
If you try out any of this book’s techniques in your current projects, let us know how it goes! We’d love to hear from you in the book’s forum.
Getting started with the source
In order to familiarize yourself with the code in the sample app, this section walks you through how the app launches and where you can find the initial view controllers. This section uses the model–view–viewmodel (MVVM) version of the sample app. While following along, don’t worry too much about understanding the architecture as you’ll explore MVVM in Chapter 5.
When launching Koober for the very first time, you’ll see two screens: the launch screen and the welcome screen.
The launch screen is implemented by
LaunchViewController and the welcome screen is implemented by
WelcomeViewController. Keep reading to see how these view controllers get onto the screen.
View controller hierarchy
Koober’s root view controller is implemented by
MainViewController, a custom container view controller.
When the app starts up, the
MainViewController is installed.
MainViewController loads by presenting the
LaunchViewController as a child view controller. When the launch screen is presented, the
LaunchViewController make up the View Controller hierarchy.
LaunchViewController then determines whether a user is signed in or not. The first time you run Koober, a user will not be signed in, so the
MainViewController will navigate from the
LaunchViewController to the
OnboardingViewController is a
UINavigationController subclass that starts by presenting the
WelcomeViewController. When the welcome screen is presented, the
WelcomeViewController make up the View Controller hierarchy.
OK, time to fire up Xcode and take a peek at the source.
Opening the source
To view Koober’s source, find the 03-example-app/final/KooberApp directory and open KooberApp.xcodeproj. Each chapter has a different version of Koober found inside each chapter’s directory.
A single Xcode project contains all the source for Koober, and the source is organized into several targets.
Xcode project targets
- Koober: This is the iOS app target for Koober and contains the app delegate and other app-specific resources, such as the info.plist. Other than the app delegate, this target does not contain any source.
- Koober_iOS: This Cocoa Touch Framework contains all the UI code specific to the Koober iOS app, such as view controllers and views.
KooberUIKit: This Cocoa Touch Framework contains code that depends on
UIKitand that could be used on other
UIKitplatforms such as
KooberKit: This last Cocoa Touch Framework contains code that does not depend on
UIKit. Therefore, this framework can be used in any Apple platform.
To get started tracing the launch sequence in code, inside Xcode’s Project navigator, open Koober/AppDelegate.swift. On the first line of
MainViewController is instantiated by the
injectionContainer is a factory that creates instances of objects with their dependencies. In this case, the
injectionContainer allows the app delegate to create a new instance of
MainViewController without knowing what other objects
MainViewController needs in order to be instantiated.
On line 45, the
MainViewController is set as the
window’s root view controller. So that’s how the
MainViewController makes its way to the screen.
Presenting the launch screen
Next, open Koober_iOS/iOSApp/MainViewController.swift. You are now in the Koober_iOS framework target where all the view controller code lives. On line 136, inside the
MainViewController subscribes to
Open KooberKit/UILayer/MainViewModel.swift. You are now in the KooberKit framework target.
On line 35, the view model’s
view property is initialized with a
MainView enum case.
Because of the initial
.launching value, when
MainViewController subscribes to the ‘view’ property’s publisher on
viewDidLoad, the view model will publish the
.launching value to the
Return to Koober_iOS/iOSApp/MainViewController.swift.
Whenever a new value is published, the subscription to the view model calls the
present(_:) method on line 70. Because the first value published is
presentLaunching method is called inside
present(_:), right after
MainViewController loads. The
presentLaunching method on line 94 adds the
LaunchViewController as a child to
MainViewController, presenting the launch screen.
Getting from launch to onboarding
Make your way to Koober_iOS/iOSApp/LaunchViewController.swift.
On line 47, during
LaunchViewController’s root view is created with a
Go the root view by opening Koober_iOS/iOSApp/LaunchRootView.swift. During initialization, on line 45, the launch view asks the view model to attempt to load a user session to see if a user is signed in.
LaunchViewModel’s source located at KooberKit/UILayer/LaunchViewModel.swift.
You can find the
loadUserSession method on line 56. Once this method finishes querying for a user session,
goToNextScreen(userSession:) is called.
When you first run Koober, there won’t be a signed-in user so the
goToNextScreen(userSession:) method will be called with
goToNextScreen(userSession:) determines that a user is not signed in, on line 82 and 83, the
notSignedIn method is called.
Next, open KooberKit/UILayer/MainViewModel.swift. Notice that this view model conforms to the
LaunchViewModel determines a user is not logged in,
notSignedIn method via the
NotSignedInResponder protocol. In other words,
notSignedInResponder. You can read more about this MVVM setup in Chapter 5.
On line 41, inside
notSignedIn, notice how
MainViewModel updates the
view property with a new
MainView enum case value,
MainViewController is subscribed to
view’s publisher, this update publishes the new
.onboarding value and tells
MainViewController to transition from it’s current presentation to presenting
OnboardingViewController. The transition happens in
Presenting the Welcome screen
OnboardingViewController is on screen, how does
WelcomeViewController get presented?
OnboardingViewController loads the same way
MainViewController loads via view model subscription. On line 63, during
OnboardingViewController subscribes to the
There’s some extra complexities in
OnboardingViewController that you don’t need to worry about just yet. The complexity exists because
OnboardingViewController is a
UINavigationController, you can read more about this in Chapter 5. The main gist is that right after
presentWelcome is called on line 88. This is how the welcome screen gets presented.
Alright! Now that you’re familiar with Koober’s source code, you’ll have no problem following along with the example code in rest of the chapters.
- Koober, a kangaroo ride-hailing app, is the example app used throughout this book.
- Koober incorporates many of the complexities found in real-world apps, such as authentication and navigation.
- A complete re-implementation of Koober accompanies each architecture chapter.
- The Koober Xcode project consists of four targets: Koober, Koober_iOS, KooberUIKit and KooberKit.
OnboardingViewControllercoordinate in order to launch Koober.