Give your app a brain with a flow controller

One of the first rules a developer learns is to separate the code handling the data and the user interface. The link between the data and UI is usually done in a controller, or, in iOS, a view controller. In most projects, view controllers are interconnected and can be very dependent with one another. That where the flow controller comes in. It serves as a link between view controllers. It's the brain of the app.

Technically speaking, a flow controller is a NSObject, and is very specific to the app you're working on. Therefore it's hard to have a base object to subclass. However, there are some rules to follow when architecting the app.

  1. Keep the application’s state

    The flow controller should always know what view controller is currently in charge. It should also poll the model objects to know the current context (feature locked/unlocked, logged in/out…).

  2. Manage the logic between view controllers

    The flow controller should control the view controllers. Because it knows the application's state, it knows when to present or dismiss a specific view controller, and which view controller should get the focus next. View controllers report to the flow controller through delegate methods so it can perform the necessary action.

  3. Orchestrate the view controllers

    The flow controller should take care of the transitions and animations between view controllers. Centralizing this in an object makes it easier to replace a custom transition or change the app’s architecture (tab bar, navigation controller…).

  4. Prevent view controller dependencies

    The flow controller should remove dependencies between view controllers. They report to the flow controller when they require an external action and don’t know about each other, the flow controller does.

  5. Handle a portion of the application

    For complex applications with a lot of view controllers, it may be better to use several flow controllers, each taking care of a different portion of the app and reporting to a master one. An application with a tab bar could have a flow controller per tab, and a main one that links them together.

I've used a flow controller in two projects so far, and it helped a lot organize and keep track of the workflow of the apps.


This post is based on a presentation I made at CocoaHeads Paris on January 9th, 2014. You can view the slides here.

Download a sample project here.

Universal App – From iPhone to iPad in 5 hours

This is the story of how I got to have an iPhone app work on iPad with a fairly different layout in just 5 hours of work. I'm sharing a few insights, but note this is not a secret recipe and it's not be applicable to all projects.

This summer, I helped my friend Luc and worked with him on a new version of his company's flagship app, Screens. Screens is a VNC client, an app that connects to a computer remotely and allows to control it. Early on, Luc had decided the app would be iOS 7 only, and that we'd start the project from scratch.

While at WWDC, as iOS 7 was unfolding before us, we exchanged about how the app could look like, and how we could take into account what we were learning that week: full-width images on iPhone, motion effects, blurs, tint color and so on.

Because the app already existed both on iPhone and iPad, we also knew from the start it would be a universal app. So as we debated on the app's design, we considered both iPhone and iPad at the same time. Luc drew a few sketches and Thomas, the designer, quickly got back to us with pretty good mockups. The app's design hasn't changed much since these mockup.

They look different, yet they are the same

The app is composed of 3 main views:

  • saved screens: the remote computers you connect to often
  • discovered computers: the computers on the local network the and remote computers
  • the remote view that is displayed when you are connected to a computer

The last one is exactly the same on iPhone and iPad, it shows a full screen live view of the screen of the computer you're connected to. We'll focus on the first two views.

On iPhone, the saved screens is the main view, and the discovered computers view pans over. On iPad, they are laid out side by side.

Same view controllers, different storyboards

There is only one view controller for each view, then there's a storyboard the iPhone layout and different storyboard for iPad. Some of the differences between iPhone and iPad are handled in the code, but most of the design and layout is done in these separate storyboards.

This is especially interesting in the case of the saved screens, where it's a list on iPhone and a grid on iPad. You can now guess we went with a collection view. It's even the same collection view cell object for both iPhone and iPad.

As we were thinking about the app's design, we kept considering how we'd have to handle the development too.

Make sure all works on iPhone before moving to iPad

So this is how we approached the app's development. We made sure we had all the functionality work on iPhone before even starting on iPad. Since we already knew how the app would look like on iPad, we knew beforehand we'd use a collection view instead of a table view on iPhone.

It took a couple of weeks to have something working pretty well on iPhone. At some point, though the app was still far from being perfect, we knew all the core functionality and logic was there for us to add the iPad layout.

Then it was breathe: set the project as a universal app, add the iPad storyboard and set the collection view's layout properties, and handle some differences in the code when necessary.

In no more than 5 hours, the iPad version of Screens was working as well as on iPhone, with a different design. I didn't expect it'd be so easy to be honest.

Plan ahead, design with development in mind

Imagine if we had used a table view on iPhone and a collection view on iPad. How would have we handled that? We’d probably have ended up with more files, a lot more code, and more pain to maintain that code.

I think the reason it went so fast is because of the way we planned the design and the development together. It doesn't work that well for all projects, but whenever you can, try to think about development effort as you design your app.


This post is based on a presentation I made at CocoaHeads Paris on December 12th, 2013. You can view the slides here.

Solving problems like a pinball

When solving a problem, imagine you build a pinball. The ball must reach the back of the play field when you hit it with the flippers. So the first thing to do is remove all the obstacles and make sure it reaches the back. Only then you can add the obstacles one by one while ensuring it keeps working every time.

That's what my teacher used to say during programming classes. When starting a new project, or a new feature, start with the most basic thing, then iterate in small increments.

Need to add a label in a view? Place it at the center with a bright color so you can't miss it. Then you can move it to its final position.

Need to connect to an API? Hard-code the URL and credentials and make the connection succeeds. Then you can create a view that asks for credentials.

Need to create a custom transition between views? Create a new 'lab' project dedicated to this task. Once it works you can move the necessary code to your big project.

Go the easy and lazy way first, then improve. Hard-code values, use bright colors, or even start a brand new little project and make sure that what you have to do works at its core. Once it works, you can add obstacles one by one.

It's something we all know but sometimes forget. I found the comparison with the pinball quite funny so it stuck in my head.

It's Not Obvious to Everyone

I don't use my phone as much as you do.

This is something my dad told me a couple times as I was teaching him a few features of iOS.

If you read this, you probably know more about iOS and technology in general than the average person. Many things that are easy and obvious to us aren't to most people.

Observations

The following are a few observations I've made over the past couple of years. I don't have numbers, but I'm pretty sure my usage of 'some people' should be more like 'most people'.

Some people don't use their phone extensively

For most people, a phone is just a tool to communicate and get entertained when they have time to kill. Because it's not an object of real interest to them, they don't have or take the time to learn new flows, icons, terms or read manuals (nobody reads manuals).

My dad often touches his iPhone's screen inadvertently; that brings the current app to another view/state and he's lost.

Some people hesitate to try when they don't know the outcome

People are not adventurous by nature. On a computer they're afraid to break everything if they try something. They approach phones the same way, and if an icon is unclear or a label confusing, they won't touch it.

Some people don't know the difference between similar technologies

What's the difference between WiFi and 3G/LTE? To most people those are the same, they're the Internet. As long as they are connected to the web they're fine, how they are connected, they don't care.

Some complain the Internet is too slow on their iPhone, they don't notice the 'E' next to the carrier's name, they don't even know what that 'E' means.

What's the difference between SMS and iMessage? The fact that it's combined in the same discussion is convenient, but many people wonder why they have blue and green bubbles.

Some people don't care about aesthetics

In the Talk Show's 56th episode, John and Guy mention several people they showed iOS 7 didn't notice the visual difference with iOS 6.

The phone is a tool, and people want to get things done with it. Take a unit converter app for example. Everyone want that kind of app on their phone because it's convenient and can be useful sometimes. You spend hundreds of hours building the most beautiful unit converter app and charge $1.99 for it. It doesn't sell because people prefer the ugly free competitor. To them both apps do the same job, but they choose the free one because they don't care as much about aesthetics as they do about price.

Avoid confusion

Use words carefully

I know it's annoying for most developers, but spending time to find the proper terms and sentences is very important if you want to avoid confusion. Avoid nerdy terms but be precise when it is necessary.

The iPhone's manual used to be a great example. Big images, a few lines of text to explain all the main concepts and features. Sadly, nobody reads manuals and the iPhone 5S doesn't ship with one anymore.

Stay close to Apple's default behaviors and visuals

People are used to the default interface, if you try to differentiate your app too much, people will be lost. Icon for a delete action? Use a trash, not a cross. Back/Close button? Put it in the top left corner of the screen because that's where it belongs on iOS.

iOS 7 is a big change and some developers are tempted to put borders around buttons or backgrounds to keep a button shape. But iOS users will get used to that new design, and quicker than you'd think because the apps they use the most are Apple's, like Mail, Phone and Messages.

Spend time observing Apple's apps, their flows, animations, and text. They're not always perfect, but most of the time they solves problems the right way. And it's a great source of inspiration.

Provide some help within your app

Whether it's a walkthrough when the user launches the app for the first time, an overlay, a sample document or an embedded help web page, your app must provide some help for the user. And it has to be easily accessible, people won't find it if they have to dig into a long view hierarchy.

It's usually not a fun thing to work on, but you can make it cool, the perfect example being StatusBoard for iPad by Panic. The guide looks like a real manual, and it's actually entertaining to experience the first time you launch the app.

The tip of the iceberg

I just scratched the surface here, there's a ton more to say about improving the user experience for mass market apps.

We spend our days working on apps, we talk about development, technology all the time between ourselves. But sometimes we need to take a step back, and think about the guys who are not in our bubble. They are the majority, we are the aliens.

Many things in technology are obvious to us, but not to most people. We have to take that into account while we build products.


This post is based on a presentation I made at CocoaHeads Montreal on October 8th, 2013. You can view the slides here.

Professional Writer

When I was 18, I almost went to university to get an English literature degree instead of studying programming. I wanted to learn languages and write well.

Fast forward to today, I write hundreds of words a day and I'm fluent in several languages. Not the same kind of writing and languages I pictured back in the day though.

I write code for a job, the audience are my co-workers who read it, and computers that generate apps out of it. The languages I use the most are called Objective-C, C, Ruby, and Javascript.

At the time I gave up on the idea to go to university, I wanted to write for a large audience about sports or a sci-fi novel. I haven't achieved any of this, but still, for the past 10 years, I've stayed in front of a computer writing... code.

It's only a month ago that I made the link between those early aspirations and my current situation. Sometimes you give something up and think it'll never show up again, only to later find out it never left.

I've recently started to write about sports, and learn Spanish. Interesting how things go in life.