Improving Swift Unit Tests with Objective-C

Did you know that improving Swift unit tests with Objective-C is something that is actually possible? Yes, it is, specifically when writing unit tests for legacy Objective-C code. One common definition of legacy code is “code without tests..”

A different definition of “legacy code” that might resonate with iOS app engineers is any code written in Objective-C. Swift is nearing its third anniversary of being announced to the world. It’s no longer the immature adolescent that can be passed by for the old reliable language, Objective-C. Instead, it’s now something that you can’t ignore as an iOS engineer. It’s the future direction of our platform. If you’re still writing Objective-C code, you should have a darn good reason as to why. Now that’s not to say you should never expect to work with Objective-C at the moment. In fact, working with Objective-C is a very real thing for most of us. Most of us don’t have the luxury of working entirely with a shiny new Swift code base. Most of us have to support older apps that have a large amount of Objective-C code. And whether or not you want to consider that “legacy code,” the fact of the matter is that it’s there, and you have to deal with it.

An Unexpected Case for Swift

Whether you’re an advanced Swifter who’s soaked in each release since the first version, to someone just getting familiar with the language, writing unit tests with Swift is something that anyone can do. Obviously you can write unit tests for Swift code with Swift code, but did you know that you can write unit tests for Objective-C code with Swift? Yep, it’s possible, and I recommend it. It’s both a low risk way to practice your Swift coding skills, while also ensuring that you aren’t creating new Objective-C code that will just need to be migrated later. And even if you already have a unit test suite for a particular Objective-C class, you can still add a Swift XCTestCase subclass and add new unit tests for that same Objective-C class. In fact, I use this approach all the time. This works especially well when working with Objective-C code bases where you’re forced to write new Objective-C to expand the functionality of the app because you need to modify existing code. You can create a new Swift unit test for verifying the new functionality added in Objective-C.

If you are setting out to add Swift tests to a project that is entirely Objective-C based, there’s one little quirk with Xcode 8 to work around. You need at least one Swift file with a bridging header in your main target for Xcode to allow you to import that target into your Swift unit tests as a module. Otherwise you will get an error, “No such module” when attempting to run your Swift test.

A Problem You’ll Encounter

After writing Swift for a while, it’s easy to to forget that back in the Objective-C world, each class generally had two files, a header file (.h) and an implementation file (.m). Best practice suggested that unless something needed to be exposed to other classes, it should go within the .m file alone. This went for method definitions and property declarations. For example, consider this UIViewController:

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) UILabel *nameLabel;
@property (strong, nonatomic) UILabel *emailLabel;

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 200, 20)];
  self.emailLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 50, 200, 20)];

  [self.view addSubview:self.nameLabel];
  [self.view addSubview:self.emailLabel];

  self.nameLabel.text = [[NSUserDefaults standardUserDefaults] stringForKey:@"name"];
  self.emailLabel.text = [[NSUserDefaults standardUserDefaults] stringForKey:@"email"];
}

@end

viewDidLoad() sets two labels based on some values stored in NSUserDefaults. Lack of dependency injection aside, coming up with an approach for writing a unit test for this method is fairly straightforward, and just as easy to implement that approach in Objective-C:

#import <XCTest/XCTest.h>
#import "ViewController.h"

// Private Category Trick to expose private properties for testing
@interface ViewController (Test)

@property (strong, nonatomic) UILabel *nameLabel;
@property (strong, nonatomic) UILabel *emailLabel;

@end

@interface ViewControllerTests : XCTestCase

@end

@implementation ViewControllerTests

- (void)testViewDidLoad_SetsLabels_Always {
  NSString *name = @"Andy";
  NSString *email = @"andyo@notanemail.com";
  [[NSUserDefaults standardUserDefaults] setObject:name forKey:@"name"];
  [[NSUserDefaults standardUserDefaults] setObject:email forKey:@"email"];

  ViewController *toTest = [[ViewController alloc] init];
  [toTest viewDidLoad];
  XCTAssertEqualObjects(name, toTest.nameLabel.text);
  XCTAssertEqualObjects(email, toTest.emailLabel.text);
}

@end

Objective-C makes it really easy to get access to the private properties for nameLabel and emailLabel, just use a private category defined within the sample .m file for the XCTestCase subclass.

Now, let’s say you’re taking my advice, and trying to write this unit test in Swift for the same Objective-C class. You’d probably start with something like this:

import XCTest
@testable import SwiftTestsForObjC

class ViewControllerTests: XCTestCase {

  func testViewDidLoad_SetsLabels_Always() {
    let name = "Andy"
    let email = "andy@notanemail.com"
    UserDefaults.standard.set(name, forKey: "name")
    UserDefaults.standard.set(email, forKey: "email")

    let toTest = ViewController()
    toTest.viewDidLoad()

    XCTAssertEqual(name, toTest.nameLabel.text)
    XCTAssertEqual(email, toTest.emailLabel.text)
  }
    
}

It’s a pretty straight forward translation from the Objective-C test. The only problem, there’s a compiler error:

The compiler is telling you that it can’t find the method definitions for nameLabel or emailLabel on ViewController. It’s actually the same problem that you would have experienced in Objective-C had the trick of using a private category not been in place. Some testing enthusiasts advocate that all code be testable. You have to balance this with other design principles. For me, I’m not going to violate the protection of encapsulation by exposing those two UILabel properties through the header file – they don’t need to be there.

So how do you fix it?

Solving The Problem, with Objective-C

Objective-C to the rescue. You can solve this problem by using a similar trick to the one that we originally used to get the Objective-C version of this test to work: a category. This time though, it won’t be a private category, instead it will be a test-target scoped Objective-C category that exposes the private properties from ViewController.

Here’s how you do it:

Step 1: Create a new header file in the group for your unit tests and name it ViewController+Testing.h (the prefix should match the class under test, and a suffix of +Testing isn’t technically required, but helps provide a context to the purpose of the file):

Step 2: Add a private category that exposes the private properties on the class you need to test:

@interface ViewController (Test)

@property (strong, nonatomic) UILabel *nameLabel;
@property (strong, nonatomic) UILabel *emailLabel;

@end

Step 3: Import the header file from the bridging header for the test target:

#import "ViewController+Testing.h"

And 💥, that’s it! Go back and attempt to compile your Swift test where you are accessing those properties, and you’ll it works!

Despite this simple example, this strategy can be used any place that you would like to write a Swift test and access private methods or properties on an Objective-C class.

I wired all this up together into a final project where you can see how it all works and try for yourself here.

How about you?

Have you dipped your toes into the international waters of crossing the borders between writing tests between Objective-C and Swift? What challenges have you encountered? How have you found it? Leave a comment and let me know!

How To Pick The Right Swift Open Source Component

With so many options available, it’s not easy figuring out how to pick the right Swift open source component. There are literally thousands, if not hundreds of thousands, of open source projects written in Swift on the web. You can find anything from simple UI widgets, to entire frameworks to support functional reactive programming. With all these choices, how do you pick the right Swift open source component to use in your project? Initially, you first have to find a component that actually meets your needs from a functionality standpoint. But after that, and arguably just as important, that open source code base must meet a minimum set of requirements to be considered for use in a production application. Here are the proposed minimum requirements to pick the right Swift open source component:

  1. Composition over inheritance
  2. Date of most recent commit
  3. History of past commits
  4. Popularity among the community
  5. Dependency manager support
  6. License
  7. Tests
  8. Proper versioning
  9. Maintenance ownership
  10. README

While most of this article’s proposed items apply to any open source project on the web, the specific examples cited in this article will be focused on performing the evaluation within the context of GitHub.

Composition Over Inheritance

You must have heard of “protocol oriented programming” by now. Have you heard what Crusty had to say? (Or if you want a quick read, here’s a good one.) When looking to pick a Swift open source component, it’s very important to look for one that prefers composition over inheritance. It should be in the forefront of your mind when looking to pick a Swift open source component. Think though how you would use the component? Look at the example usage. Does the component require you to subclass something in order to use it? Does the component require you to override base implementations of a super class in order to customize behavior? If so, steer clear. This is a sign of an inheritance-based customization model. Instead, look for projects that provide behavior customization through protocol conformance. Look for Swift open source projects that require you to compose the component as a variable rather than subclass something. These are signs that the project has already made an effort to code in the Swift way, rather than hang on to techniques of the past.

Date of Most Recent Commit

This is an easy one to measure. Simply look at the date of the most recent commit in the project. There’s no hard and fast rule that says the most recent commit should be within X number of days, but it shouldn’t be so old that the current version(s) of Swift or Xcode aren’t supported. Additionally the date of the most recent commit is also a good quick representation of how active the project is under development. If the most recent commit is months old, yet there have been many recent Issues opened with no response from the author, that’s not a good sign.

swift open source component

History of Past Commits

Aside from the date of the most recent commit, it’s also a good idea to peak at the history of past commits. While the most recent commit could be a couple days ago, that could be the first commit in an entire year. That’s not good. It’s good to look for a steady stream of commits. A large number of commits can be a double edged sword as well. If you observe a large frequency of commits, that can also mean that the project has not matured to a stable state yet. And additionally, if not paired with a solid release versioning strategy where designated “releases” are indicated as such, a high frequency of commits can indicate instability of the current code base without a clear designation of when the last “stable” commit was.

Popularity Among The Community

A popular project is a sign of a healthy project. The more people using a project, the more likely it will be that the project will be up to date to begin with, and also stay that way. Github makes this easy. Two things I look for to evaluate popularity are: number of Stars, and number of different committers. These aren’t steadfast measures though. Many popular projects only have a single committer. Just things to peak at. It’s unlikely that a project has widespread community support if there are a small number of Stars and a single committer.

swift open source component

Dependency Manager Support

There are three popular iOS dependency managers available today, and each has a different level of maturity: CocoaPods, Carthage, and Swift Package Manager. If you haven’t used any of these, or are unfamiliar with what a “dependency manager” is, you should absolutely stop right now and go try one out. They will change your life, especially if you routinely use third party code in your iOS applications. When evaluating a Swift open source component, it’s always a good idea to check whether the project has already provided support for at least one of the dependency managers. This is a good indication that the project is mature, and also has at least a minimal release versioning strategy. Those familiar with the tools above will know to look for a Podfile, a Cartfile or a Package.swift file. If the project doesn’t have this it’s not the end of the world, you can be the first to take action with the author to attempt to move the project in that direction. Use the author’s willingness or responsiveness as a followup indicator of whether you want to build close ties with the project.

License

If there was one personal choice amongst this whole list, this is it. Everyone needs to choose for themselves which open source license is appropriate. The only unacceptable red flag to steer away from in a Swift project on the web is to have NO license.

Tests

It wouldn’t be the Clean Swifter blog if there wasn’t a pitch for tests. Unfortunately, this is probably the least likely thing to find in open source projects. Don’t consider it a hard requirement, but consider it a HUGE bonus if the project has tests. It’s an even bigger bonus if the tests are connected to a public continuous integration build process (like Travis or BuddyBuild) with an indication of test results in the README.

Proper Versioning

This is another style of icing on the cake, and may have varied levels of important depending on the popularity and size of the project. Sometimes for smaller projects, the HEAD of the master branch can be consider the most recent “release.” That can get sticky though, because it may require you to manually keep track of which revision you are using in your project. It also leaves it open to interpretation the advertised stability of the current revision. A solid versioning strategy indicated by the Releases view in Github is a good indicator of a well maintained project.

Maintenance Ownership

Finally, the last thing to consider when getting in bed with a Swift open source project is how maintenance of the project is handled. How many different people have committed to the project? How many open Pull Requests are there for the project? Are the Pull Requests stale, or actively under collaboration? How many open Issues are there? Are they under active collaboration? Does the owner of the repository even allow others to collaborate? Your guaranteed to eventually find something you’d like to tweak when using a Swift open source component. Make sure that you have an idea from the start of how you would ultimately get that tweak in place when the time comes.

README

There’s something about well polished documentation that gives a shine of professionalism on Swift open source components. For GitHub projects, this is often in the form of the README. It’s front and center when looking at a project. If the README is thorough, up to date, typo-free, and well formatted, that goes a long way to indicate the quality of the underlying code. If the README is empty, wrong, or sparse, that’s a red flag. Also, look beyond the README into the other documentation. Take a peak a commit messages and documentation in the code itself. Is it well documented?

Wrap Up

Even with the most rigorous of evaluation of Swift open source components, you should make careful architectural decisions and design choices so that the coupling between your code and the third party code is loose and easy to be changed. This is a hard lesson to learn if you don’t do it. And don’t forget, the best thing about open source code is that you can see the actual source! Beyond anything else mentioned in this article, feel free to dive down into the source and make an evaluation of the code itself. After all, you can code too.

What’s missing from this article? Are there any other tricks that you use when picking a Swift open source component?

Happy cleaning.

PS – If you use CocoaPods, the team has done a lot to automate much of this list in the form of their Pod Quality Index. You can get a quick summary of the overall quality of any given CocoaPod. Here’s an example for Alamofire. Here’s the documentation on how it is calculated.

Dependency Injection with Storyboards

Dependency injection with storyboards is not always straightforward, yet there are a couple techniques that can help you achieve programming nirvana. Dependency injection is a great technique that can help enable more modular and easily testable code. Unfortunately, since Storyboards can often mask how things like transitioning from one view controller to another works under the covers, there aren’t always obvious hooks for implementing dependency injection with Storyboards. Don’t stray to the dark side, singletons are not the answer. There is a way to the light, and I’ll show you a couple techniques for using dependency injection with Storyboards.

What Dependency Injection Is

Have you heard colleagues or friends talk about “dependency injection” but you never really knew what it was? It’s a fancy term for a simple concept. James Shore sums it up really well:

Dependency injection means giving an object its instance variables. Really. That’s it.

Here’s an example view controller definition:

class FirstViewController: UIViewController {
  var persistenceStack: PersistenceStack?
}

FirstViewController defines an instance variable persistenceStack that is open to any other file in the same module. This means that any other class, struct, protocol, whatever, that has access to an instance of FirstViewController may provide it the persistenceStack. Voila, that’s dependency injection. It’s nothing more complicated like that. Said a different way, FirstViewController has a dependency on PersistenceStack and that dependency is provided, or injected, by something else.

Why Dependency Injection Is Important

Dependency injection is an important principle in clean software engineering. The most important reason that you should use dependency injection is that it detaches the implementation of behavior from the interface of behavior. Classes that are open to have their dependencies injected mean that they can be decoupled from the underlying implementation of those dependencies. It’s much easier to purely program to an interface or protocol if you don’t need to know anything about the underlying implementation of the dependency under use.

Imagine you are on a large development team working on a giant iOS application with hundreds of thousands of lines of code. You’re on the “Front-End” team where you focus on the development of the user interface. You spend most of your time in Interface Builder and view controllers. Elsewhere in the company, possibly in a different office, is the “Persistence-Tier” team. The Persistence-Tier team is responsible for writing the mission critical portion of the application that saves things to disk, and keeps those objects in synch with the server-side backend. The thing is, as smart as the Persistence-Tier is, they are constantly changing their mind about the underlying implementation for their piece of the application. Lucky for you, the team has agreed upon a protocol-based dependency injection implementation for access into the persistence layer. As a team member working on view controllers all day, dependency injection prevents you from needing to worry about things like:

  1. How to instantiate the persistence stack.
  2. Whether the persistence stack has been properly configured.
  3. What is the underlying implementation of the persistence stack (eg. CoreData, SQLite, Realm, etc.).
  4. How does using a persistence stack affect automated testing

Instead, you can trust that this dependency will be properly provided to your view controller from some other place, and all you have to do is use it. Remember, it’s just an instance variable that is populated by something else. Your view controller has one less responsibility, and thus is that much closer to achieving the Single Responsibility Principle.

Testability

If you’re reading this blog, you’re probably interested in automated testing. Dependency injection is probably the single easiest way to improve the testability of your iOS code, well any code really, but particularly your UIKit-ladden iOS code. Rather than be tied to the underlying implementation of dependencies, you can provide your own implementation from your test classes, just like you would between classes in the real application. You can now easily stub out things like that persistence layer.

Why Dependency Injection With Storyboards Is Hard

Break out of the role play and back to the real world where most apps are created by a few people on a small team, if not a single person. While the analogy of a giant organization no longer holds true, the need to be able to swap persistent store implementations is something frequently encountered. There’s always a hot new player in the game. Now that you’re bought-in to dependency injection, it’s time to consider how to use the in iOS applications. Storyboards were introduced in iOS 5. Storyboards provide a holistic Interface Builder oriented way to create the user interface for your application. Rather than creating one-off xibs per view controller that then require you the engineer to wire together, a Storyboard allows you to design all your view controllers in one place where you can view all of them at one time, and wire them together such that the relationships between the screens is easily comprehendible in a single glance.

One problem of Storyboards is that they obscure some underlying details of how view controllers actually connect together and communicate. Specifically, when working with a Storyboard-based application, you are rarely writing code in a view controller that manually creates another view controller and brings it onto the screen. Instead, you are relying on segues, and unless you go out of your way to write code to prepare for a segue to happen, or manually trigger a segue, it’s easy to think that the magic of the Storyboard does everything for you.

For example, here’s a Storyboard:

Dependency Injection with Storyboards

This Storyboard represents an application with a navigation controller stack where the root view controller has a button to push a deeper view controller onto the stack. All that behavior provided for free from the Storyboard. Now how in the world would you use dependency injection to provide a dependency to the view controllers in this application? Good question, there are a couple ways.

Dependency Injection with Storyboards

Here are several techniques for implementing dependency injection with Storyboards.

Passing a dependency to an initial view controller

A common pattern you’ll see in iOS applications that use dependency injection is that specific dependencies for the application are instantiated in the custom UIApplicationDelegate for the application. From there, they are then passed into the initial view controller for use throughout the application. Here’s how you can do that. Consider the following Storyboard:

Dependency Injection with Storyboards

A single view controller is designated the Initial View Controller for the application. That means, that view controller will be the first one shown when the application is launched. There’s little corresponding code in the app’s custom UIApplicationDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

  return true
}

The Storyboard does all the magic for ensuring that view controller is shown on launch. To inject a dependency into that view controller, you need to first create the dependency, and then set it on the view controller. You can use the window and its corresponding rootViewController to get that hook onto the Initial View Controller, like this (assuming a similar implementation of FirstViewController from earlier in this article):

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

  let persistenceStack = PersistenceStack()

  if let firstViewController = window?.rootViewController as? FirstViewController {
    firstViewController.persistenceStack = persistenceStack
  }
  return true
}

Simply use access the rootViewController through the window and then combine that with an if let to downcast it to the specific implementation you need, FirstViewController. Then you have the hook you need and you can inject the dependency.

Passing a dependency to tab bar view controllers

Passing a dependency to view controllers that are part of a tab bar is a little more involved, and the technique is totally inspired from Greg Heo via his awesome two-part raywenderlich.com video tutorial series on Core Data. Storyboards simplify the creation of UITabBar based applications to the point where there is no code representing the creation of the tab bar or its controller. Of course, you can go above and beyond and add code to customize behavior, but you have to know where to do it. Here’s a technique to inject dependencies into view controllers of a tab bar. Imagine an app with this basic Storyboard:

Dependency Injection with Storyboards

It’s nearly the project template for a Tab Based Application. Two view controllers coming off of a UITabBarController. The UITabBarController is designated the Initial View Controller in the Storyboard. In the same project, the AppDelegate has very little code at launch:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  return true
}

There’s literally nothing happening in that method, the Storyboard is doing everything. Well, lucky for you, application(_:didFinishLaunchingWithOptions:) does actually get called, so it’s the perfect spot to instantiate meaty dependencies and provide them to the initial set of view controllers for the application. But before you modify that code, there’s an important intermediate step to take to ensure everything will be glued together properly, create a protocol! Create a protocol that each view controller will implement that indicates it can have it’s persistence dependency injected. This way, you can write polymorphic in the app delegate to inject the dependency, without needing to know the type of each and every view controller in the tab bar. Create this protocol somewhere:

protocol PersistenceStackClient {
  func setStack(stack: PersistenceStack)
}

Anything conforming to this protocol indicates that it can have a PersistentStack set on it.

Next, update any and all view controllers in the tab bar with an extension that indicates protocol conformance:

extension FirstViewController: PersistenceStackClient {
  func set(stack: PersistenceStack) {
    self.persistenceStack = stack
  }
}

And rinse repeat for each view controller in the tab bar. There are ways to further abstract this so as not to repeat code, but the sample will be simple for now.

Now you can add the magic glue to the app delegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

  let persistenceStack = PersistenceStack()

  if let tab = window?.rootViewController as? UITabBarController {
    for child in tab.viewControllers ?? [] {
      if let top = child as? PersistenceStackClient {
        top.set(stack: persistenceStack)
      }
    }
  }
  return true
}

It’s not doing much, but it’s a clever technique. Here’s what’s happening step by step:

  1. Instantiate the dependency.
  2. Grab the rootViewController.
  3. Loop through the child view controllers in the tab bar, and for each that is a PersistentStackClient, set its persistenceStack.

Boom, that’s it, dependency injected into a tab bar controller! See how the protocol allows you to set the PersistentStack in a loop without needing to know the exact type of the view controller?

Passing a dependency from view controller to view controller

Passing a dependency from one view controller to another can be done using:

prepare(for segue: UIStoryboardSegue, sender: AnyObject?)

prepare(for:sender:) is a method defined in UIViewController that may be overridden in your implementations. It’s specifically called right before a segue off of that view controller happens. The provided UIStoryboardSegue has details about specifically which segue was triggered since there could be more than one segue off of a view controller. Included with these details is the destination view controller.

Continuing our earlier example, imagine you have:

class FirstViewController: UIViewController {
  var persistenceStack: PersistenceStack?
}

class SecondViewController: UIViewController {
  var persistenceStack: PersistenceStack?
}

Each view controller has a dependency that may be injected, persistenceStack. Here’s how you may inject persistenceStack from FirstViewController into SecondViewController assuming that they are wired together with a segue in the Storyboard:

class FirstViewController: UIViewController {
  var persistenceStack: PersistenceStack?

  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destination = segue.destination as? SecondViewController {
      destination.persistenceStack = persistenceStack
    }
  }

}

In this implementation of prepare(for:sender:), the destination is retrieved from the UIStoryboarSegue and if it is a SecondViewController then it’s persistenceStack is set, and thus the dependency is injected!

Wrap up

These couple techniques for using dependency injection with Storyboards will bring the cleanliness of your iOS code to the next level. Bart Jacobs’ has a great quote about dependency injection: “It felt as if I graduated as a programmer and no longer needed the singleton pattern to glue the pieces of a project together.” Here’s another good resource titled Nuts and Bolts of Dependency Injection in Swift that you will find helpful, and goes much more in detail on the basics of dependency injection in Swift, and why you should use it. Are you a dependency injection zealot yet? Are you already using dependency injection with Storyboards? How are you using it in your Swift iOS apps? Let everyone know in the comments!

Happy cleaning!

SFSpeechRecognizer Tips for iOS 10

Did you know that there’s a new iOS 10 API for transcribing audio in your iOS apps? I didn’t know that this was possible myself until I came across the Speech Framework introduced in iOS 10. In fact, I was actually watching one of Sam Davies’ screencasts on Ray Wenderlich’s new video site called Audio File Speech Transcription (both the screencast and the new videos site are fantastic by the way) where he covered how the API can be used to transcribe an audio file. The screencast itself is a fantastic short overview of how to use the framework to create an app that transcribes 90’s rap music files. I’m not going to try and recreate a tutorial on the basics of the API. Instead, when trying it out myself I discovered a couple nuances not mentioned in Sam’s screencast. Here’s a couple SFSpeechRecognizer tips.

Requires A Device

Use of SFSpeechRecognizer, the main class that makes speech transcription possible, will not actually transcribe anything unless you are running your app on a device (as of Xcode 8 beta 6). This was a surprise to me, especially considering that speech transcription of an audio file, rather than microphone input, has nothing to do with a physical device. I’m wondering if it has something to do with the underlying implementation of Siri and something that only exists on the actual device. Regardless, you are lucky enough to have access to a Bool on SFSpeechRecognizer called isAvailable. This Bool simply indicates whether speech recognition is available at the time of usage. I was actually banging my head trying to figure out how to get Sam’s sample project to actually work within the iOS Simulator. His screencast seemed to transcribe speech no problem in the app I was viewing on screen. Finally I looked closer and noticed that he was screensharing from an iOS device through Quicktime! Mystery solved! Either way, don’t make the same mistake as me and wonder why code like this didn’t work:

guard let recognizer = SFSpeechRecognizer() else {
  return
}

if !recognizer.isAvailable {
  print("Speech recognition not available")
  return
}

Timeouts

The other interesting discovery I made when playing around with SFSpeechRecognizer is that there is an undocumented limitation on how big of a file can be transcribed at once. I’m still playing around with the details as to where the limits are, but I have discovered, that longer running SFSpeechURLRecognitionRequest will timeout. I’m not even talking that long, like I had problems with a 5 minute video. For example, I tried transcribing my video Replace Temp With Query that is 4 minutes and 45 seconds long, and this was all the text that was returned before the timeout happens:

Hey what’s up everybody Danny from clean swiffer.com I’m here to show you another we factor in this week from our valors book we factoring in improving the design of existing time this week we’re gonna take a look at the re-factoring called replaced temp with Cory please temp with berries are factoring that’s a lot like expect nothing but there’s one difference it’s a little more specific with a place template query we’re going to specifically target temporary variables within our code and extract them into reusable piece of code so

Ya, not much (and not very accurate either). Either I should create a Radar for this, or Apple only intends for this API to be used for transcription of short audio clips. Time will tell.

Partial Transcription To The Rescue

Despite the undocumented timeout putting a crimp in my plans for using the Speech Framework in a couple longer running use cases, another Bool caught my eye: shouldReportPartialResults. It turns out my setting this flag to true, the Speech Framework will periodically provide transcribed results to you as they are discovered. Just set the value to true and you’ll see results continuously reported as they are determined:

let request = SFSpeechURLRecognitionRequest(url: url)
request.shouldReportPartialResults = true
recognizer.recognitionTask(with: request) {
  (result, error) in
  guard error == nil else { print("Error: \(error)"); return }
  guard let result = result else { print("No result!"); return }

  print(result.bestTranscription.formattedString)
}

Transcribing Realtime Playback

Despite these two shortcomings of short timeouts and requiring a device (which I hope Apple will fix at some point as the API matures), speech transcription is a really cool technology. Did you notice that voicemails in iOS 10 are automatically transcribed? It’s freakin awesome that you can glance at text for a voicemail rather than needing to listen?

Anyway another really cool real-world example of use of the Speech Framework is in the GitHub open source project Speech Recognition from zats. Apparently with some help from Apple, he came up with a way to transcribe a video on the fly. There’s some gnarly AVFoundation Objective-C code that made this possible. Be sure to take a look at his project and give it a go. And in fact, I’m wondering if I can use the techniques here to work around the timeout limitation I experienced with raw use of SFSpeechRecognizer. (Update: Turns out it did!)

Back Story

If you’ve read this far about SFSpeechRecognizer tips, I might as well bore you with some details on the back story as to why the SFSpeechRecognizer API caught my interest. With the videos I create for this site, it’s important to me to provide a transcription of the videos. I realize that watching a video isn’t always possible, so I like having a text alternative. It probably also helps with SEO as well. The thing is, transcribing the videos is a tedious process. For about a 5 minute video, it takes me about 30 minutes to transcribe it, and I type fast. Additionally, that’s only raw transcription. I’d like to do so much more. For example, I think the Realm videos are really well done. Specifically, two things I like are the links to jump to specific spots in the video from the transcription, and I also like the source code samples in the transcription. For me to do this it would take more time, so in attempt to look for a quick and easy fix to buy back some time, I figured I could use the new iOS 10 Speech Framework to code a speech transcription app to automatically transcribe my videos for me. I’m still working on it and definitely leveraging these SFSpeechRecognizer tips.

They say that necessity is the mother of all invention, right?

Wrap Up

How will you be putting these SFSpeechRecognizer tips to work? Have you had a chance to try out the new Speech Framework or any of the SFSpeechRecognizer APIs? Have you run into any other tricky spots or overcome any hurdles?

Happy cleaning.

Swift API Design Guidelines: Highlights

The Swift API Design Guidelines could be one of the most important things I’ve found towards writing cleaner Swift code. Have you seen them yet? I hadn’t actually looked at them until I watched the WWDC video, “Swift API Design Guidelines.”. When chatting with a coworker about which WWDC video to watch during some downtime, I’ll admit that this video didn’t really catch my eye. As someone who doesn’t really write much “framework” type code for other people to consume besides those I directly work with, I didn’t immediately relate to the description for the video:

Swift 3 introduces new API Design Guidelines specifically crafted to the unique character of Swift for clear, concise code. This talk will explore the philosophy behind the Swift API Design Guidelines and their application throughout the Swift Standard Library and the Cocoa and Cocoa Touch APIs. See how this API transformation will affect your Swift code and learn how to ensure a smooth transition to Swift 3. Learn how Swift 3 imports Objective-C APIs and how to expose rich Swift interfaces for existing Objective-C libraries.

Well having watched the video, and then read through the actual design guidelines on Swift.org, I’m bought in, and recommend you take a look as well.

The Swift API Design Guidelines is like an instruction manual for how to craft the “words” in your code: how you name variables, parameters, method names. It tells you how to interweave the words in your code with the surrounding documentation. By becoming familiar with the Swift API Design Guidelines, you’ll both write code that is consistent with the community, and the APIs that are being created within the frameworks right out of Apple and the Swift team. It’s a win/win proposition.

Here are the highlights of the Swift API Design Guidelines for me:

The “ed/ing” rule

The presenter in the WWDC video summed this rule up as the “ed/ing” rule (that makes it easy for me to remember). In the Swift.org documentation, it’s referred to as Name functions and methods according to their side-effects in the Strive for Fluent Usage section. The guideline suggests that often, “A mutating method will often have a nonmutating variant with similar semantics, but that returns a new value rather than updating an instance in-place.” According to the ed/ing rule, append ed or ing to the nonmutating version. For example:

Mutating

x.sort()
x.append(y)

Nonmutating

z = x.sorted()
z = x.appending(y)

Omit Needless Words

Boy, if there’s one bad habit that is leftover from Objective-C is really wordy method names, particularly be repeating words. For example, just look at the NSMutableArray Objective-C class documentation and take a peak at how many times the word “object” appears. Methods like this are all over the Objective-C Foundation API:

- (void)addObject:(ObjectType)anObject;
- (void)removeObject:(ObjectType)anObject;

Just look at how many times the word “object” appears in the class documentation for NSMutableArray. As a result, this verbosity made its way into the code that I wrote as well.

Well this is a no no in Swift. The Swift creators are striving for a balance of conciseness AND clarity.

Although Swift code can be compact, it is a non-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system…

The last part of this section is relevant. It’s the strong type system that allows for the NSMutableArray API to be redesigned as:

func add(_ anObject: AnyObject)
func remove(_ anObject: AnyObject)

Notice how the word “Object” was removed from the method name itself? That’s exactly what is meant as a “needless word” in the guideline “Omit Needless Words.” This is because consumers of this API can rely on the strong type system of Swift to only pass objects to the method that are of the defined type of the parameter. This is just one example where Swift API Design Guideliness lead us to more concise code through omitting needless words. Now that you’re aware of it, you’ll start to see this all over and should even apply it to your own API design.

Also, be sure to check out the sections in the Swift API Design Guidelines for Name variables, parameters, and associated types according to their roles and Compensate for weak type information. Detailed examples are not included here, but those guidelines provide good companion structure how to achieve clarity while also ommitting needless words. Remember, don’t strive for brevity over clarity. Just like the WWDC presenter mentioned, you don’t want to have to constantly be switching to the API docs because the API is so terse.

Grammatical English Phrases

Method and function names should read like grammatical English phrases. I really like this one, and I feel like this is one good habit I’ve carried from my dark days as a Java programmer. This is also covered in the String for Fluent Usage section of the Swift API Design Guidelines. A good sanity check for your method and parameter names is to read the line of code aloud and ask yourself, “Is this grammatically correct English? Is this how I would conversationally say it?” If yes, then you probably are on to a good API design. If not, you should probably reconsider it. Examples right from Swift.org of good API design that grammatically makes sense:

x.insert(y, at: z)          // “x, insert y at z”
x.subViews(havingColor: y)  // “x's subviews having color y”
x.capitalizingNouns()       // “x, capitalizing nouns”

Bad design that doesn’t read aloud well:

x.insert(y, position: z)
x.subViews(color: y)
x.nounCapitalize()

Other Random Cool Stuff

Documentation

In the handful of programming languages that I’ve professionally written, I’ve never come across such a succinct yet well defined set of guidelines for writing code documentation. It’s right at the top of the Fundamentals section of the Swift API Design Guidelines. There are short and sweet points to consider when writing documentation for your Swift code, and also how to make your comments compatible with how Xcode might represent them in generated documentation.

Conventions

The Conventions section is really cool too. There are a lot of one-off suggestions to help clarify everything from when to document Big-Oh efficiency, to how to capitalize your variable and method names.

Wrap Up

I can’t urge you strongly enough to check out the Swift API Design Guidelines on Swift.org. I can tell you that in my opinion it is one actionable thing that you can do to improve your Swift code, today. It’s simple, clear, and instructional manner makes it really easy to understand. Your code will be more consistent with itself, and code written elsewhere in the community. Who wouldn’t want that?

Happy cleaning.

XCTest Target Membership Rule #1

I just had to learn a lesson the hard way, and wanted to pass on to you what I’m going to call the XCTest Target Membership Rule. It took some head banging of mine to discover this rule, and I don’t want you to go through the same pain.

The XCTest Target Membership Rule

The actual implementation files for your app should not be included with the Target Membership for your XCTest target.

xctest target membership

If you were to check the box next to TestStaticTests you would start to see this error in the Console when running your tests:

objc[14049]: Class ViewController is implemented in both <path cut>/TestStatic.app/TestStatic and <path cut>/TestStaticTests.xctest/TestStaticTests. One of the two will be used. Which one is undefined. 

The runtime for XCTest is telling you that it has found the same class defined in two places, the two targets for which you specified the file should be included. And furthermore, you’re also being told that the behavior with regard to which implementation is used will be “undefined.” The funny thing was, I actually found this error message to be misleading. I found that in practice, both copies of the implementation are actually used if you can believe that!

Here’s an in-depth question I posted on StackOverflow documenting the odd behavior I noticed, and included a sample project demonstrating it as well.

Background

These past few weeks I’ve been working on an older project, specifically AWeber Stats. If you notice, that app hasn’t been updated since April 2015, that’s a while. As a result a lot of the dependencies were out of date, so one thing the team set out to do was update the dependencies, and CocoaPods seemed like a good place to start. We were previously on version 0.34.1 and planned to update to 1.0.1 (which at the time of this writing is the latest version). We use Ruby Gems to manage the dependency versions for CocoaPods specifically. This allows us to have per-project control of which version of CocoaPods end up being used. This gives us the reassurance that we must explicitly designate the desire to update a given project’s CocoaPod’s version, and thus accordingly test and verify the update.

I move forward with the update, bumping the version of CocoaPods to 1.0.1 as defined in our Gemfile. CocoaPods 1.0 actually defines a new schema for Podfiles so I subsequently migrated the Podfile to the new format, and successfully ran pod install. Everything has gone smoothly up to this point. Then I opened my Xcode workspace and attempt to run our test suite.

100s of failures.

In addition to the failures, I saw many instances of that Console warning from earlier:

...One of the two will be used. Which one is undefined.

Now the thing is, remember, at this point I hadn’t yet discovered the XCTest Target Membership Rule. And as it turns out, nearly every implementation file in the project for the app target, also existed in membership for the test target. And in fact, as I dusted the cobwebs off of my mind, and thought back to the original work on the project, I specifically remember needing to designate those implementation files as having membership in the test target. Specifically, it was errors like this that would appear of the class under test was not part of the test target:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_MyArrayController", referenced from:
      objc-class-ref in MyArrayControllerTests.o

So where did the need to include that file with the test target go? Why was Xcode now telling me that I shouldn’t include these files with both targets?

Well I never got to the bottom of it. I have two guesses at this point: something either in Xcode, or in CocoaPods changed to modify the behavior how XCTest integrates with the classes under test.

Closing Thoughts

I’m still digging to get to the bottom of this. In the meantime, I will not forget the XCTest Target Membership Rule. A couple other lessons surfaced:

  1. Don’t wait to keep your project up to date – It’s easy to launch an app on the store, or hand it off to a client, and semi-forget about it. The app is live, attracting customers, and functioning well. Just remember, at some point it will either need to be updated or die. And the longer you wait, the harder it will be to bring it up to contemporary standards. It’s much easier to make more frequent small changes, than wait 15 months, return to an unfamiliar code base, and try to bring it up to speed.
  2. Know your tool chain – I’m still not fully aware of what changed between the last app update and today such that such a fundamental piece of project functionality changed. I’m taking this as a kick in the butt to get my head wrapped around third party dependencies being used. And if you can’t do that (for whatever reason – time, complexity, interest, etc.), don’t use them. There are plenty of ways to manually install third party code, or even write it from scratch. Of course other people have already invented the wheel, just don’t blindly use the tools without a foundational understanding of how to troubleshoot them when they go wrong.

Happy cleaning.

UIRefreshControl in iOS 10

Did you know that adding a UIRefreshControl in iOS 10 to a table view, a collection view, or a scroll view has never been easier? UIRefreshControl is now a first class citizen in all of these scrollable views and officially supported by the iOS SDK. Having fought through hacked solutions to use a UIRefreshControl in anything but the officially supported UITableViewController in the past, I’m really pumped to see this. This change for iOS 10 first caught my eye in the WWDC 2016 session, What’s New in UICollectionView in iOS 10 (which was a really good session by the way).

How It Works

The key to easily adding a UIRefreshControl to a UITableView, a UICollectionView, and a UIScrollView is the UIRefreshControlHosting protocol. Just like UIRefreshControl in iOS 10, this is also new in iOS 10. It’s a protocol adopted by UIScrollView. And coincidentally, UITableView and UICollectionView inherit from UIScrollView so they easily get this behavior.

Adding a UIRefreshControl in iOS 10

Here’s how simple it is to add a UIRefreshControl in iOS10:

let tableView = UITableView()
let rc = UIRefreshControl()
tableView.refreshControl = rc

Yep, it’s that dirt simple. Want to add a UIRefreshControl to a UIScrollView? It’s just as easy!

let scrollView = UIScrollView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

And want to add it to a UICollectionView? Well, you probably get the idea:

let collectionView = UICollectionView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

Now don’t forget to add a target to the UIRefreshControl so it has some behavior associated with it. Luckily, nothing has changed with that API, so it’s just as you remember it from pre iOS 10 days. Here’s a full example with a UITableView:

override func viewDidLoad() {
  super.viewDidLoad()
  let tableView = UITableView()
  let rc = UIRefreshControl()
  rc.addTarget(self, action: #selector(TableViewController.refresh(refreshControl:)), for: UIControlEvents.valueChanged)
  tableView.refreshControl = rc
  view.addSubview(tableView)
}

func refresh(refreshControl: UIRefreshControl) {
  tableView.reloadData()
  refreshControl.endRefreshing()
}

Refreshingly Simple

If you got this far, you probably aren’t rolling your eyes at how easy this is. If you’re questioning whether this is worth a blog post or not, fine. I believe it is. This is a subtle, yet awesome API change coming in iOS 10. I love to see that Apple continues to refine their API and adding niceties like this for developers. I look at this change and think, “Ya, this is how it always should have been.” Thank you, Apple. Has there been anything else on the edges that you’ve noticed and felt good about?

Happy cleaning.

Asynchronous Xcode UI Testing

As I continue to delve into Xcode UI tests, I’m starting to discover some of the lesser advertised benefits and drawbacks of the tool. One specific nuance that has caught my eye is how to deal with asynchronous Xcode UI testing. Xcode UI tests are asynchronous in that they simulate end user interaction with your application. End user interaction triggers animation (and in some cases waiting on remote services), and animation doesn’t happen instantaneously. There is a disconnect between the speed at which the lines of code in your tests can be executed, and whether the simulator (where the app under test is located and running) can keep up or not. In most cases, the simulator can’t keep up. As a result, you need to explicitly instruct your tests to wait for the app to catch up in the simulator. There are two ways to do this that I’ve been using.

Smart Waiting

waitForExpectationsWithTimeout(_:handler:)

When performing asynchronous Xcode UI testing, it’s often really useful to be able to verify something has appeared on screen. This way you know that the application is a certain state, and can continue executing a test script. For example, imagine an application with a tab bar, selecting a different tab should show a different view controller. If you were writing a test that relied on features within the second tab of the tab bar, it’s important have some assurances that when you instruct your test to tap the second tab, the tab actually appears. Furthermore, the act of waiting for something on screen can also act as a test in itself. If tapping the second tab doesn’t actually show what you expect, something probably went wrong and the test should fail.

Inspired from Joe Masilotti’s Cheat Sheet for Xcode UI testing, here’s how you can leverage waitForExpectationsWithTimeout(_:handler:) to verify that something appeared on screen:

// 1
let goLabel = self.app.staticTexts["Go!"]
let exists = NSPredicate(format: "exists == true")
expectationForPredicate(exists, evaluatedWithObject: goLabel, handler: nil)

// 2 
app.buttons["Ready, set..."].tap()

// 3
waitForExpectationsWithTimeout(5, handler: nil)
XCTAssert(goLabel.exists)

Here’s an explanation for this code:

  1. Define a NSPredicate to be used in a XCTestExpectation to verify that the Go! button exists in the app.
  2. Tap the Ready, set… button.
  3. Wait for the Go! button to appear.

waitForExpectationsWithTimeout(_:handler:) will repeatedly look for the NSPredicate to be true within the timeout provided, in this case 5 seconds.

This approach to verifying that something exists on the screen is incredibly useful. It’s very much like my old favorite KIF API waitForViewWithAccessibilityLabel. The thing is, it isn’t perfect.

Not Perfect

I’ve observed a number of cases when using this approach has led to false positives that an element “exists” on the screen. Essentially the XCTest UI framework observes that the element exists, but isn’t actually tappable, or in a state that a human-end-user would consider “on the screen.” If seen this most often happen when this technique is used in combination with animations happening in conjunction with the test action. For example, if you have an application that taps a button, which triggers a navigation controller to push a new view controller onto the stack, there’s a relatively slow animation that happens. With the predicate approach laid out above, asynchronous Xcode UI testing will actually identify incoming screen elements as “existing” before they are in their “final resting spot” at the end of the animation. So if you gate further steps of your test on the presence of something on the screen as determined by the XCTest UI framework, you’ll get false positives that the element is on the screen and ready for further interaction. Essentially, Xcode UI tests will tell you, “Yes, that button exists on the screen,” but in reality it isn’t yet “on the screen.” Don’t worry though, there’s a solution, and it’s incredibly dumb.

Dumb Waiting

sleep(1)

In those cases when you need to a little extra pause in your asynchronous Xcode UI testing in response to an asynchronous event like an animation, I’ve found that just using a sleep(1) goes a long way. Essentially this will block your tests from continuing for the specified duration of time, while the application under test is allowed to continue. To update the example code above, I add the sleep(1) in conjunction with the NSPredicate technique as follows:

let goLabel = self.app.staticTexts["Go!"]
let exists = NSPredicate(format: "exists == true")
expectationForPredicate(exists, evaluatedWithObject: goLabel, handler: nil)

app.buttons["Ready, set..."].tap()

waitForExpectationsWithTimeout(5, handler: nil)
XCTAssert(goLabel.exists)
sleep(1)

Notice that the sleep(1) happens right after the NSPredicate is determined to be true. This follows my discovery that Xcode UI tests identify things as “existing” before they are actually on screen. Using the NSPredicate technique with the sleep(1) let’s you verify the presence of specify UI elements, while also giving the app time to complete long running tasks like animations before continuing.

What’s funnier is that this sample code shown on screen at WWDC 2016 caught my eye:

asynchronous Xcode UI testing

Turns out, Apple uses the same technique!

Assertions in Closures

Another useful technique in asynchronous Xcode UI testing is to perform assertions on user-interface elements in response to closure execution. Often, indication of completion of long running calls like web service retrievals will be implemented with closures. I’ve written Xcode UI tests that explicitly call the web service separate from the application in order to cross-check data returned. Basically, I’ll ensure that the data the raw web service returns matches what is in the application. Whether this is your use case or not, you can use this pattern to make assertions in the closure on callback completion. The only requirement is that Xcode UI API calls need to happen on the main thread:

// 1
let expectation = expectationWithDescription("API Request Complete")
var response: Response?

// 2
RequestUpManager().get(id: "3688840") {
  (response: Response?, error: NSError?) -> () in
  
  if let response = response {
    response = response

    // 3
    dispatch_async(dispatch_get_main_queue(),{
      // Verify there is something on screen that matches what the API provided.
      let cell = self.app.cells.elementBoundByIndex(0)
      XCTAssertEqual(cell.staticTexts[response!.position].identifier, "Position")
      expectation.fulfill()
     })
  }
  else {
    // 4
    XCTFail("Unexpected object returned from API")
    expectation.fulfill()
  }
}
// 5
waitForExpectationsWithTimeout(WAIT_TIMEOUT, handler: nil)
  1. Use expectations to keep the test running while the request loads.
  2. Synchronously load data from the API.
  3. Tell the main thread to verify what’s on screen. (This will crash if not done on the main thread).
  4. Explicitly fail the test if unwrapping the optional data returned from the API fails.
  5. Using XCTestExpectations, wait for the asynchronous code to complete.

Wrap Up

These are just a couple little tricks I’ve learned for asynchronous Xcode UI testing when taking my first dive into the API. It’s always nice to get in and try out a tool beyond what’s shown in documentation or videos, you get a much better handle for nuances of what’s available. Have you come up with any solutions for these challenges in asynchronous Xcode UI testing?

Happy cleaning.

How to Disable Tests in Xcode

It’s easy to disable tests in Xcode, but not entirely obvious. A lot of people give Xcode flack in terms of how far behind other IDEs it is with regard to its support for automated testing. I don’t entirely disagree with this. On the other hand, it’s come so far from just five years ago and I’m thankful for that.

Why Disable Tests

You might be wondering, if I’ve spent all this time writing tests, why would I ever want to disable tests in Xcode? I’m not advocating permanently disabling them, instead, I’m advocating disabling them temporarily to speed up your development or to unblock progress. Just this week, I returned to an old project of mine, one that hasn’t had an app store update in over a year. It still uses CocoaPods version 0.33.0, and Swift 1. Needless to say, it needed some work getting it up to speed. (Side note: I have a lot of ammunition for future blog posts on how to NOT let a project get this stale, but we’ll save those for a future camp fire). First, I needed to get the project to actually compile. Second, I needed to get the tests passing. And finally, I needed to update our continuous integration machines and jobs to also compile and successfully run the tests. I had my work cut out for me.

When working with a project this old, sometimes advanced techniques like TDD aren’t immediately useful if you can’t even get the project to simply compile. When working through compilation errors and test failures at a large scale, it’s useful to selectively turn off a subset of the errors or test failures so you can eliminate noise, focus on a piece of the problem, and make progress. You can easily disable tests in Xcode in two ways: disable compilation, and disable test execution. Both of these are scheme changes. Here’s how:

How To Disable Tests

Disable Tests From Building

To simply disable all your tests from building, you can do this in the Scheme editor. From the menu bar, select Product -> Scheme -> Edit Scheme.

In the left hand bar, select Build.

Then in the main pane, you can disable tests from compiling for any action in your project. If you’re project is in a really bad state, you can disable tests from compiling when running your application.

disable tests in Xcode

By disabling any of those checkboxes, when you run your application, anything in the associated targets will not be compiled.

Disable Tests From Running

Similarly, you can use the Scheme Editor for selectively turning tests and off. Still in the Scheme Editor, select Test in the left hand bar. Then, in the main pane, you’ll see each target associated with tests. The checkbox will let you enable or disable the tests from being run when you run tests for your project (Command-U, or Product -> Test).

disable tests in Xcode

Disabling an entire target may not be as granular as you’d like. In fact, it’s pretty coarse. You can expand any of the targets in that list and see specific test classes, and then selectively enable or disable tests by test class. And if that isn’t granular enough, you can drill one level deeper and then selectively turn tests on or off by test method!

disable tests in Xcode

Give it a try.

xcodebuild in Xcode 8

One thing I’m really excited for in Xcode 8 is that xcodebuild, the command line interface for building Xcode projects, was updated with similar functionality. With xcodebuild in Xcode 8 you can selectively pick which tests are built and executed. The use case is a little different for this tool. xcodebuild is often used as part of a continuous integration setup. With the new changes, you no longer need to compile tests to run them. xcodebuild will be able to run tests previously compiled. This means that you can compile your app and tests on one machine, and then distribute the load of testing it across other machines!

disable tests in Xcode

To build you app for testing, but not actually run the tests:

xcodebuild build-for-testing -workspace <path>
                             -scheme <name>
                             -destination <specifier>

Then you can use the produced bundle on different machines to run the tests without compiling! Combine that with the following steps for selectively running tests, and you’ll be able to distribute the execution of your test suite across different machines, in parallel!

To selectively specify which tests to run for xcodebuild:

xcodebuild test -workspace <path>
                -scheme <name>
                -destination <specifier>
                -only-testing:TestBundleA/TestSuiteA/TestCaseA
                -only-testing:TestBundleB/TestSuiteB
                -only-testing:TestBundleC

You can also specify tests to be skipped:

xcodebuild test -workspace <path>
                -scheme <name>
                -destination <specifier>
                -skip-testing:TestBundleA/TestSuiteA/TestCaseA

Don’t Abuse It

With great power comes great responsibility. Please don’t disable tests in Xcode, either from running or compiling, and leave it that way. That’s like driving without a seatbelt. Only do it if you are working in effort to improve your project. I know that working with a dusty and stale project isn’t the only time that it may be useful to disable tests in Xcode. I’m sure you’ll find your own reasons. I’d love to hear what they are.

Happy cleaning.

IBOutlet Local Reasoning: What, why, and how

Did you watch Protocol and Value Oriented Programming in UIKit Apps from WWDC 2016 yet? I did and it’s one of my favorite sessions yet. It was essentially a part 2 from the WWDC 2015 session, Protocol-Oriented Programming in Swift. It even included a cameo of Crusty. I really liked the session because it gives some plain talk explanation towards improving your Swift code through basic functional programming techniques, and it was specifically attractive to me because of this year’s session’s focus on UI code. UIKit code is filled with object-oriented techniques and patterns like MVC and subclassing that it’s hard for a chiseled object-oriented veteran to learn new tricks like functional programming.

State is Bad

Relying on instance variables in your objects leads to buggy code. Furthermore, it leads to code that’s not just buggy, but also simply hard to debug. You should strongly consider any case where you introduce an instance variable that will be used for state management. Consider the following view controller:

class ViewController: UIViewController {

  var total = 0

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if (total > 0) {
      print("total bigger than 0")
    }
  }

  func incrementTotal() {
    total = total + 1
  }
}

This code has an outrageous example of relying on an instance variable to determine state of the object. total is an Int. The major problem I have with code like this is the conditional if-statement in viewDidAppear(_:). This is a simple example, so it may not seem problematic to you. Imagine if the view controller had significantly more code, where total was referenced all over the code. Imagine there were numerous places where total was getting assigned to. Imagine there were numerous places where total was being used for conditional checks. Imagine that even external classes were reading and modifying total. Imagine all the places you would have to check and be aware of to ensure that total behaved correctly such that the view controller properly functioned. It quickly grows out of control. Code like this has been the source of more bugs than I can count in my UIKit programming. It’s why functional programming is so attractive to me, despite how hard it is for my head to wrap around some of the concepts.

Local Reasoning

One of the absolute most attractive things about functional programming in my mind is the lack of “side effects” of your code. Essentially, you strive to write code that does not have side effects, where there is a single “source of truth.” This is one of the cores of value oriented programming. When working towards this, you begin to write code that is much easier to debug and much less buggy to begin with. It’s much easier to understand code just by looking at it. One of the biggest anti-patterns of object oriented code is managing state of an object through a instance variable.

In the WWDC 2016 session Protocol and Value Oriented Programming in UIKit Apps the concept of “Local Reasoning” is introduced. It’s a semi-official computer science term that describes code which contains little to no side effects. Local reasoning is that “when you look at the code right in front of you, you don’t have to look at the rest of the code or project to know how it behaves.” This is really attractive because when you look at a piece of code, you can quickly have confidence that you understand what it does because you don’t need to look in many places. Instance variables that control object state are the enemy of local reasoning. For example, looking at the code above, any reference to total contains the caveat that there could be any number of things modifying total throughout program execution. You can never rely on the value of total to actually make a decision about the state of the program.

IBOutlet Local Reasoning

Of course you can’t actually remote all instance variables from your code. You’ll inevitably find certain scenarios where some state must be stored. One common such example are IBOutlets. IBOutlets are special snowflakes in the software design world. Pretty much any rule about software design may not apply when using IBOutlets. When using a Interface Builder file or a Storyboard, you’ll need to subclass UIView or UIViewController and link user interface elements from Interface Builder to the code through IBOutlets. The thing is, IBOutlets take the form of instance variables in code.

class ViewController: UIViewController {
  @IBOutlet weak var toggleSwitch: UISwitch!
}

So how can you apply IBOutlet local reasoning to improve your code? My coworker Mike Stanziano had a really useful idea on how to do this: use a property observer on the IBOutlet.

Let’s say that you want to create a UISwitch in your storyboard. The state of this switch will correspond to a boolean value in a persistence layer, the example will use UserDefaults. Initializing the value usually would happen in viewDidLoad() like:

override func viewDidLoad() {
  super.viewDidLoad()
  let keep = UserDefaults.standard().bool(forKey: "ToggleValue") ?? false
  toggleSwitch!.setOn(keep, animated: false)
}

Maybe you could use the Extract Method refactoring to move those two lines to their own method, but my point is that this code immediately violates local reasoning and starts you off on the wrong foot in using your IBOutlet. I’d consider this code part of initialization of the UISwitch, so it doesn’t make sense to put it in viewDidLoad() aside from the semi-artificial rule put in place by UIKit in that views should be setup in viewDidLoad().

Inspired by Protocol and Value Oriented Programming in UIKit Apps, my colleague Mike came up with something better:

@IBOutlet weak var toggleSwitch: UISwitch! {
  didSet {
    let keep = UserDefaults.standard().bool(forKey: "ToggleValue") ?? false
    toggleSwitch!.setOn(keep, animated: false)
  }
}

This code moves the initialization of the UISwitch‘s state out of viewDidLoad() to a place that I argue is much more appropriate, where the IBOutlet is defined. Since IBOutlets don’t get init’d in code, their definition is the closest thing we have towards an actual instantiation. Now, when you look at the definition of the IBOutlet, you immediately know how it’s initial state is configured. This is right in line with the local reasoning – “when you look at the code right in front of you, you don’t have to look at the rest of the code to know how it behaves.”

And of course, writing a unit test for this code is extremely straightforward.

func testSwitch_DisplaysStoredSwitchState_WhenToggled() {
  // Start the switch on
  UserDefaults.standard().set(true, forKey:"ToggleValue")
  UserDefaults.standard().synchronize()

  let toTest = ViewController()
  let testSwitch = UISwitch()
  toTest.toggleSwitch = testSwitch

  XCTAssertTrue(toTest.toggleSwitch.isOn)
}

No need to call viewDidLoad() from your test. Simply set the desired value on the UISwitch and verify the behavior.

Clean Code is Clear Code

I love the principle of local reasoning in your code. I’m all about writing clean code, I even named this blog after it. Give IBOutlet local reasoning a try and I think you’ll like it. Clean code is enabled by clear code, and local reasoning leads you to clearer code. Give it a try. Here’s a project on GitHub with this code all wired up using Swift 3 and Xcode 8.

Happy cleaning.