Test-Driven iOS: Passing Information With Segues

Reading Time: 2 minutes

In past posts of test-driven iOS, we have talked about instantiating view controllers with dependencies. What if we want to pass information from one view controller to the next one?

Let’s explore how we would test-drive a storyboarded iOS application that passes information from a master list view controller to a detail view controller.

We’ll write an application about fruit!

fruit

FROOOOOOOT

Our work will require two steps:

Step 1: Test


import XCTest
import Hamcrest
import FutureKit
@testable import FruitApp
class ListOfFruitsViewControllerTest: XCTestCase {
func testShowsFruitDetailsWhenFruitRowIsTapped() {
let orange = FruitAppFruit(name: "Orange")
fruitService.stubbedFruits = [orange]
fruitListController.tableView(fruitListController.fruitTableView, didSelectRowAtIndexPath: NSIndexPath(forRow: 0, inSection: 0))
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, false)
assertThat(navigationController.topViewController, presentAnd(instanceOf(FruitDetailViewController.self)))
let fruitDetailsController = navigationController.topViewController as! FruitDetailViewController
assertThat(fruitDetailsController.fruit, presentAnd(equalTo(orange)))
}
}

Here we tap on one element in the master view controller and make sure that the next presented view controller is the detail view controller. We also check that the object the detail view controller will display—an orange!—has been set on the detail view controller.

If we’re not presenting the view controller manually, then we cannot call an initializer on it that sets this property for us. So how do we pass it in?

Step 2: prepareForSegue()


import UIKit
import FutureKit
class ListOfFruitsViewController: UITableViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "goToFruitDetailsSegue") {
if let
fruitDetailController = segue.destinationViewController as? FruitDetailViewController,
selectedFruit = self.selectedFruit
{
fruitDetailController.fruit = selectedFruit
}
}
}
}

This handy method gives us access to the view controller that our segue will present right before we present it. This means that we can get ahold of our destination view controller and set our selected fruit.


import UIKit
class FruitDetailViewController: UIViewController {
var fruit: FruitAppFruit?
}

The detail view controller itself has a field attribute on it that you saw us set in the last code snippet. we’ll have access to this throughout the view controller, so we can display all our orange information in there!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.