First Contact with AppKit for iOS Developers (Under the Radar #26)

During my rather relaxed late evening workouts I catch up on podcasts now. Although I don’t enjoy listening to people talk (I prefer reading), this is a great source of inspiration and seems to be the premier way in which people share their experience.

Marco Arment and David Smith run Under the Radar. In episode 26, they talk about Marco’s deviations into AppKit—Mac app development. (Their shows are always under 30 minutes, so I suggest you give it a try.)

Marco’s app Quitter is available for free. He couldn’t put it into the Mac App Store because its main feature is to quit other apps. That doesn’t work with Sandboxing. So Marco had to release it directly.

I found a few things especially noteworthy:

  • Direct distribution means you have to worry about installation, updates, and payments yourself. It’s more work. So Marco made it free. (P.S.: I wrote a book on direct distribution.)
  • Marco was rather afraid to ship an update: maybe he didn’t test thoroughly and introduced a bug; it seemed to me he missed the safety net of app reviews.
  • Then again, shipping a bug fix update is fast and easy, too. It takes zero time to make an update available to customers.

The absence of app reviews in direct distribution is both frightening and liberating. I am afraid to ruin my customers’s lives with every Word Counter update I ship. It’s true, you can break things. But you can also make things right within the hour. You don’t have to wait for anybody else. (Even though iOS app review times have improved a ton, from 7 to 2 days!)

I am astonished that both Marco and David have years of experience working with UIKit but didn’t ship a single Mac app in the meantime. Or do contract work back in the day. “iOS exclusive” sounds insane to me, but for them it has worked quite well!

What’s your experience? Do you remember your first contact with AppKit? Are you afraid to try? Comment, email, or tweet me your response!

iOS View Architectures and VIPER Explained

There’s an excellent overview of MVC, MVP, MVVM, and VIPER in iOS with sample codes by Bohdan Orlov of Badoo I recommend you read.

There are two main takeaways:

  1. One of the commenters nailed it: any MV* variant focuses on architecting view components. Only VIPER takes the application as a whole into account. MVC by itself is an architectural pattern, but not an approach to app architecture in itself.
  2. A UIViewController belongs into the user interface layer and is, in fact, a composite view itself. That’s confusing at first because of the name. This insight will liberate you from thinking that a view controller is sufficient to glue data to UIKit components. There’s room for a whole application between these two.

The VIPER example is exceptionally good. It takes VIPER’s heritage of Clean Architecture and Hexagonal into account and defines the Interactor through an output port. In that way Bohdan’s sample code is more east-oriented and cleaner than what you’d usually find on the topic:

protocol GreetingProvider {
    func provideGreetingData()
}

protocol GreetingOutput: class {
    func receiveGreetingData(greetingData: GreetingData)
}

class GreetingInteractor : GreetingProvider {
    weak var output: GreetingOutput!

    func provideGreetingData() {
        let person = Person(firstName: "David", lastName: "Blaine") // usually comes from data access layer
        let subject = person.firstName + " " + person.lastName
        let greeting = GreetingData(greeting: "Hello", subject: subject)
        self.output.receiveGreetingData(greeting)
    }
}

Usually, you’d model provideGreetingData() as a function that returns the data to the caller. This will cause trouble in async processes of course.

You see in the full example that the amount of types seem to explode. Don’t be afraid of that as long as you can assign each type a specific responsibility. Then it won’t turn into the mess everyone seems to be afraid of.

Having used VIPER in apps myself, I see a problem with the names, though. XYZInteractor and XYZPresenter aren’t much better than XYZController in terms of expressiveness. On top of that, a concrete Presenter is always modelled to act as event handler, too. Don’t let this fool you into thinking you absolutely have to do this yourself – there’s always room to separate writing from reading operations, or event handling from view population.

Don't Build on El Capitan Without Checking App Transport Security

I got burned this week. Pretty bad. I shipped a small bugfix release for my Mac app Word Counter a couple of days ago to prepare for the “big one” coming this week. Naturally, I built that version on my El Capitan dev machine. I pushed the update to my server. Updates using Sparkle worked. – But now users of that version cannot ever update to the next version. Because I haven’t thought about ATS.

Continue reading …

VIPER iOS App Architecture Approach

Teaser image
VIPER
VIPER, illustrated. Picture credit: Jeff Gilbert, Conrad Stoll, and Lin Zagorski of Mutual Mobile, used with permission.

Ryan Quan of Brigade Engineering has published an article about using the VIPER iOS app software architecture. Their write-up is really good: message passing is illustrated with code samples – and they even use neat box graphs!

I use a VIPER-like approach in my apps, too, and I’d like to invite you to try it for yourself. VIPER is inspired by Clean Architecture and Hexagonal.

In a nutshell, you decouple the view controllers from event handling from data management. You introduce so-called “Wireframes” to set up a module or “stack” of objects to display a view controller with certain data. The Wireframes set up everything once. Afterwards, event handlers take over, called “Presenters”. They perform transitions between scenes. View controllers do not much more than setting up the view and reacting to IBActions.

This will make maintaining code easier because the view controllers are finally put on a diet. Figuring out how data has to flow differently takes some getting used to. I’m going to write about this in a future post.