NSFetchedResultsController Core Data Swift 3

Why Use NSFetchedResultsController?

So far, we’re at exactly the same point we were using the SQLite3 method. However, we didn’t have to write nearly as much code (notice the absence of a FailedBankDatabase class constructing raw SQL statements), and adding other functionality such as insert/delete operations would be much simpler.

However, there’s one notable thing that we could add pretty easily with Core Data that could give us huge benefits to performance: use NSFetchedResultsController.

Right now we’re loading all of the FailedBankInfo objects from the database into memory at once. That might be fine for this app, but the more data we have the slower this will be, and could have a detrimental impact to the user.

Ideally we’d like to load only a subset of the rows, based on what the user is currently looking at in the table view. Luckily, Apple has made this easy for us by providing a great utility class called NSFetchedResultsController.

So, start by opening up file and adding a new NSFetchedResultsController instead, Ok, now onto the fun part – creating our fetched results controller!

 fileprivate lazy var fetchedResultsController : NSFetchedResultsController<Messages> = {
 // Initialize Fetch Request
 let fetchRequest: NSFetchRequest<Messages> = Messages.fetchRequest()
 
 fetchRequest.predicate = NSPredicate(format: "topic.userId == %d && topic.status == %d && topic.type == %d", argumentArray: [self.ForUser, 0, 1])
 
 // Add Sort Descriptors
 let sortDescriptor = NSSortDescriptor(key: "time", ascending: true)
 fetchRequest.sortDescriptors = [sortDescriptor]
 
 // Initialize Fetched Results Controller
 let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.context, sectionNameKeyPath: nil, cacheName: nil)
 fetchedResultsController.delegate = self
 
 return fetchedResultsController
 }()

This should look pretty familiar to the code that we used to have in viewDidLoad, to create a fetch request to pull out the FailedBankInfo objects. However, there’s a lot of new stuff here so let’s discuss…

First, any time we use an NSFetchedResultsController, we need to set a sort descriptor on the fetch request. A sort descriptor is just a fancy term for an object we set up to tell Core Data how we want our results sorted.

The cool thing about sort descriptors is they are very powerful. Not only can you sort on any property of the object you are returning, but you can sort on properties of related objects – just like we see here! We want to sort the objects based on the close date in the FailedBankDetails, but still only receive the data in FailedBankInfo – and Core Data can do this!

A very important part is the next statement – to set the batch size on the fetch request to some small size. In fact, this is the very reason we want to use the fetched results controller in this case. This way, the fetched results controller will only retrieve a subset of objects at a time from the underlying database, and automatically fetch mroe as we scroll.

So once we finish tweaking the fetch request with the sort descriptor and batch size, we just create a NSFetchedRequestController and pass in the fetch request. Note it takes a few other parameters too:

  • For the managed object context, we just pass in our context.
  • The section name key path lets us sort the data into sections in our table view. We could sort the banks by State if we wanted to, for example, here.
  • The cacheName the name of the file the fetched results controller should use to cache any repeat work such as setting up sections and ordering contents.

So now that we have a method to return a fetched results controller, let’s modify our class to use it rather than our old array method. First, update viewDidLoad as follows:

//Activate fetchedResultsController
 do {
 try fetchedResultsController.performFetch()
 } catch {
 let fetchError = error as NSError
 print("Unable to Fetch Messages")
 print("\(fetchError), \(fetchError.localizedDescription)")
 }

All we do here is get a handle to our fetchedResultsController (which implicitly creates it as well) and call performFetch to retrieve the first batch of data.

Then, update numberOfRowsInSection:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
 return fetchedResultsController.sections![section].numberOfObjects
 }

And update cellForRowAtIndexPath like the following:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
//fetch message
 let message = fetchedResultsController.object(at: indexPath)

cell.LblMessage.text = message.message

return cell
}

Ok one more thing – we need to implement the delegate methods for the NSFetchedResultsController.

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
 //Begin table update on will change content
 tableView.beginUpdates()
 }
 
 func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
 
 //Reload table indexpaths accorgind to the change in database
 switch type {
 
 case .insert:
 tableView.insertRows(at: [newIndexPath!], with: .fade)
 
 case .update:
 tableView.reloadRows(at: [indexPath!], with: .fade)
 
 default:
 tableView.reloadData()
 }
 
 }
 
 func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
 //End table update on did change content
 tableView.endUpdates()
 }

Compile and run your project, and it should look the same. However, if you examine the debug output you will see something very amazing…

SELECT 0, t0.Z_PK FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
    ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK
    ORDER BY t1.ZCLOSEDATE DESC
total fetch execution time: 0.0033s for 234 rows.

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY,
    t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
    ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE
    t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
    ORDER BY t1.ZCLOSEDATE DESC LIMIT 20
total fetch execution time: 0.0022s for 20 rows.

SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZSTATE, t0.ZCITY,
    t0.ZDETAILS FROM ZFAILEDBANKINFO t0 LEFT OUTER JOIN
    ZFAILEDBANKDETAILS t1 ON t0.ZDETAILS = t1.Z_PK WHERE
    t0.Z_PK IN  (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
    ORDER BY t1.ZCLOSEDATE DESC LIMIT 20
total fetch execution time: 0.0017s for 20 rows.

You can see here that behind the scenes, the NSFetchedResultsController is getting a list of IDs from FailedBankInfo, in the proper sort order. Then, as the user pages through the table, it loads one batch at a time – rather than loading all of the objects into memory at once!

This would have been a lot more code to do with raw SQLite – and is just one of the many reasons why using Core Data can save time and increase performance.

NSFetchedResultsController Core Data Swift 3

Define Credit/Debit Card Type In Swift 3

Sourec Code:

enum CardType {
case
Unknown,
Amex,
Mastercard,
Visa,
Discover

//https://en.wikipedia.org/wiki/Payment_card_number
static func fromString(string: String) -> CardType {
if string.isEmpty {
//We definitely can’t determine from an empty string.
return .Unknown
}

guard string.rw_allCharactersAreNumbers() else {
assertionFailure(“One of these characters is not a number!”)
return .Unknown
}

//Visa: Starts with 4
//Mastercard: Starts with 2221-2720 or 51-55
//Amex: Starts with 34 or 37
//Discover: Starts with 6011, 622126-622925, 644-649, or 65

if string.hasPrefix(“4″) {
//If the first # is a 4, it’s a visa
return .Visa
} //Else, we need more info, keep going

let firstTwo = string.rw_integerValueOfFirst(characters: 2)
guard firstTwo != NSNotFound else {
return .Unknown
}

switch firstTwo {
case 51…55:
return .Mastercard
case 65:
return .Discover
case 34, 37:
return .Amex
default:
//Can’t determine type yet
break
}

let firstThree = string.rw_integerValueOfFirst(characters: 3)
guard firstThree != NSNotFound else {
return .Unknown
}

switch firstThree {
case 644…649:
return .Discover
default:
//Can’t determine type yet
break
}

let firstFour = string.rw_integerValueOfFirst(characters: 4)
guard firstFour != NSNotFound else {
return .Unknown
}

switch firstFour {
case 2221…2720:
return .Mastercard
case 6011:
return .Discover
default:
//Can’t determine type yet
break
}

let firstSix = string.rw_integerValueOfFirst(characters: 6)
guard firstSix != NSNotFound else {
return .Unknown
}

switch firstSix {
case 622126…622925:
return .Discover
default:
//If we’ve gotten here, ¯\_(ツ)_/¯
return .Unknown
}
}

var expectedDigits: Int {
switch self {
case .Amex:
return 15
default:
return 16
}
}

var image: UIImage {
switch self {
case .Amex:
return ImageName.Amex.image
case .Discover:
return ImageName.Discover.image
case .Mastercard:
return ImageName.Mastercard.image
case .Visa:
return ImageName.Visa.image
case .Unknown:
return ImageName.UnknownCard.image
}
}

var cvvDigits: Int {
switch self {
case .Amex:
return 4
default:
return 3
}
}

func format(noSpaces: String) -> String {
guard noSpaces.characters.count >= 4 else {
//No formatting necessary if <= 4
return noSpaces
}

let startIndex = noSpaces.startIndex

let index4 = noSpaces.index(startIndex, offsetBy: 4)
//All cards start with four digits before the get to spaces
let firstFour = noSpaces.substring(to: index4)
var formattedString = firstFour + ” ”

switch self {
case .Amex:
//Amex format is xxxx xxxxxx xxxxx
guard noSpaces.characters.count > 10 else {
//No further formatting required.
return formattedString + noSpaces.substring(from: index4)
}

let index10 = noSpaces.index(startIndex, offsetBy: 10)
let nextSixRange = Range(index4..<index10)
let nextSix = noSpaces.substring(with: nextSixRange)
let remaining = noSpaces.substring(from: index10)
return formattedString + nextSix + ” ” + remaining
default:
//Other cards are formatted as xxxx xxxx xxxx xxxx
guard noSpaces.characters.count > 8 else {
//No further formatting required.
return formattedString + noSpaces.substring(from: index4)
}

let index8 = noSpaces.index(startIndex, offsetBy: 8)
let nextFourRange = Range(index4..<index8)
let nextFour = noSpaces.substring(with: nextFourRange)
formattedString += nextFour + ” ”

guard noSpaces.characters.count > 12 else {
//Just add the remaining spaces
let remaining = noSpaces.substring(from: index8)
return formattedString + remaining
}

let index12 = noSpaces.index(startIndex, offsetBy: 12)
let followingFourRange = Range(index8..<index12)
let followingFour = noSpaces.substring(with: followingFourRange)
let remaining = noSpaces.substring(from: index12)
return formattedString + followingFour + ” ” + remaining
}
}
}

IMAGE:

Define Credit/Debit Card Type In Swift 3

Unit Test Private Methods

Unit testing a Swift project is quite different from unit testing a project written in Objective-C. If you’re used to the flexibility of the Objective-C runtime, then it may feel as if your hands are tied behind your back. Right?

Access Control

While access control is a very welcome addition with many benefits, it can complicate unit testing, especially if you’re new to unit testing. You probably know that you can apply the testable attribute to an import statement in a test target to gain access to entities that are declared internal.

Image

While this is a convenient addition, it doesn’t give you access to private entities in a test target. This brings us to the question of the day. How do you unit test private entities?

Wrong Question

The short answer to this question is simple. You cannot access private entities from another module and this also applies to test targets. Plain and simple. That’s what access control is for.

But that isn’t the answer to the question. If you ask how to unit test private entities, then you’re asking the wrong question. But why is that?

Mind Your Own Business

Why do you declare an entity private? What’s your motivation for doing so? Take a look at the following example.

Image

I’d like to unit test the AccountViewViewModel structure. As you can see, the AccountViewViewModel struct exposes two internal computed properties and it also defines a private method. The expiresAtAsString computed property offloads some of its work to the private parse(date:) method. Testing the internal computed properties is straightforward.

Image

But how do we test the private method? We cannot access the private method from the test target. But why should we unit test the private method? We marked it as private for a reason. Right? And that brings us to the answer to the question we started with. We don’t test private methods.

Unit Testing the Public Interface

By unit testing the public interface of the AccountViewViewModel struct we automatically or implicitly unit test the private interface of the struct. You have the task to make sure the public interface is thoroughly tested. This means that you need to make sure every code path of the AccountViewViewModel struct is covered by unit tests. In other words, the suite of unit tests should result in complete code coverage. That includes public, internal, and private entities.

If we enable code coverage in Xcode and we run the unit tests of the AccountViewViewModelstruct, we can see that some code paths are not executed.

Image

This tells us that the unit tests are incomplete. We can ignore the code path for the fatal error. I never unit test code paths that result in a fatal error, but that largely depends on how you use fatal errors in your projects.

We can increase code coverage for the AccountViewViewModel struct by adding one more unit test.

Image
Image

Implementation and Specification

It’s important to understand that we’re testing the specification of the AccountViewViewModelstruct. We’re not testing its implementation. While this may sound similar, it’s actually very different. We’re testing the functionality of the AccountViewViewModel struct. We’re not interested in how it does its magic under the hood.

The key takeaway is that private entities don’t need to be unit tested. Unit testing is a form of black-box testing. This means that we don’t test the implementation of the AccountViewViewModel struct, we test its specification.

This doesn’t mean that we’re not interested in the implementation, though. We need to make sure the suite of unit tests covers every code path of the entity we’re testing. Code coverage reports are invaluable to accomplish this.

Unit Test Private Methods

RxSwift and RxCocoa Introduction

What are RxSwift and RxCocoa?

RxSwift and RxCocoa are part of the suite of ReactiveX (usually abbreviated to “Rx”) language tools that span multiple programming languages and platforms.

While ReactiveX started as part of the .NET/C# ecosystem, it has grown extremely popular with Rubyists, JavaScripters and particularly Java and Android developers.

RxSwift is a framework for interacting with the Swift programming language, while RxCocoa is a framework that helps make Cocoa APIs used in iOS and OS X easier to use with reactive techniques.

ReactiveX frameworks are designed to be helpful by providing a common vocabulary for certain tasks used repeatedly across different programming languages. This (theoretically) makes it easier to focus on the syntax of the language itself, rather than wasting time figuring out how to map a common task to each new language.

Observables and Observers

Two concepts to be aware of for this tutorial are the Observable and the Observer.

  • An Observable is something which emits notifications of change.
  • An Observer is something which subscribes to an Observable, in order to be notified when it has changed.

You can have multiple Observers listening to an Observable. This means that when the Observable changes, it will notify all its Observers.

The DisposeBag

RxSwift and RxCocoa also have an additional tool to help deal with ARC and memory management: the DisposeBag. This is a virtual “bag” of Observer objects which are disposed of when their parent object is deallocated.

When deinit() is called on the object which has a DisposeBag as a property, the bag is “emptied” and each disposable Observer is automatically unsubscribed from what it was observing. This allows ARC to take back memory as it normally would.

Without a DisposeBag, you’d get one of two results: either the Observer would create a retain cycle, hanging on to what it’s observing indefinitely, or it could get deallocated out from under your object, causing a crash.

So to be a good ARC citizen, remember to add any Observable objects to the DisposeBag when you set them up. That way, they’ll be cleaned up nicely for you.

Getting Started

Let’s get to the chocolate! The starter app for this tutorial, Chocotastic, is available here. Download the zip file and and open the project in Xcode.

Note: The project utilizes CocoaPods, so you’ll need to open the Chocotastic.xcworkspace file in Xcode.

Build and run the application. Eventually you’ll see the screen, which lists several kinds of chocolate you can buy from Europe, along with respective prices. Tapping on a chocolate row will add that product to your cart. Tap on the cart in the upper right-hand corner to be taken to a page where you can either check out or reset the cart. If you choose Checkout, a credit card entry form will be presented:

Later in the tutorial, you’ll come back to set this up using purely reactive programming. Tap the Cart button to return to the cart summary, then tap the Reset button to return to the main screen with an empty cart.

The Starting Point: Non-reactive

Now that you’ve seen what the application does, it’s time to examine how it works. Open ChocolatesOfTheWorldViewController.swift, where you’ll see some pretty standard UITableViewDelegate and UITableViewDataSource extensions.

There’s also a method, updateCartButton(), which updates the cart button with the current number of chocolates in the cart. This is called from two different places: in viewWillAppear(_:), whenever the view controller is about to be shown, and in tableView(_:didSelectRowAt:), after a new chocolate has been added to the cart.

These are both imperative ways of changing the count: you must explicitly call the method to update the count.

Right now you have to keep track of where you’re changing the value, but you’re going to rewrite the code to use a reactive technique. That way, the button will update on its own no matter how or where the count is changed.

RxSwift: Making the Cart Count Reactive

All of the methods referring to items in the cart use a ShoppingCart.sharedCart singleton. Open up ShoppingCart.swift and you’ll see a pretty standard setup of a variable on the singleton instance:

var chocolates = [Chocolate]()

Right now, changes to the contents of chocolates can’t really be observed. You could add a didSet closure to its definition, but that would only get called when the entire array, rather than any of its elements, was updated.

Fortunately, RxSwift has a solution. Replace the line creating the chocolates variable with this:

let chocolates: Variable<[Chocolate]> = Variable([])
Note: This change will cause a bunch of errors to show up in the sidebar, but you’ll fix those in a moment.

This syntax can be a little hard to wrap your head around, so it helps to understand what’s going on under the hood.

Rather than setting chocolates to a Swift array of Chocolates objects, you’ve now defined it as a RxSwift Variable that has a type of a Swift array of Chocolate objects.

Variable is a class, so it uses reference semantics—meaning that chocolates refers to an instance of Variable.

Variable has a property called value. This is where your array of Chocolate objects is stored.

The magic of Variable comes from a method called asObservable(). Instead of manually checking valueevery time, you can add an Observer to keep an eye on the value for you. When the value changes, the Observer lets you know so you can react to any updates.

The downside of this setup is that if you need to access or change something in that array of Chocolates, you must do it via the value property rather than directly; that’s why the compiler is throwing a tantrum and a fistful of errors. Time to fix them up!

In ShoppingCart.swift, look for the method totalCost() and change this line:

return chocolates.reduce(0) {

to:

return chocolates.value.reduce(0) {

In itemCountString(), change:

guard chocolates.count > 0 else {

to:

guard chocolates.value.count > 0 else {

and change:

let setOfChocolates = Set<Chocolate>(chocolates)

to:

let setOfChocolates = Set<Chocolate>(chocolates.value)

Finally, change:

let count: Int = chocolates.reduce(0) {

to:

let count: Int = chocolates.value.reduce(0) {

In CartViewController.swift, find reset() and change:

ShoppingCart.sharedCart.chocolates = []

to:

ShoppingCart.sharedCart.chocolates.value = []

Back in ChocolatesOfTheWorldViewController.swift, change the implementation of updateCartButton()to this:

cartButton.title = "\(ShoppingCart.sharedCart.chocolates.value.count) \u{1f36b}"

and in tableView(_:didSelectRowAt:), change this line:

ShoppingCart.sharedCart.chocolates.append(chocolate)

to the following:

ShoppingCart.sharedCart.chocolates.value.append(chocolate)

Whew! After all that, Xcode will be happy and there should be no errors. Now you can take advantage of the fact that chocolates can now be observed!

Go to ChocolatesOfTheWorldViewController.swift and add the following to the list of properties:

let disposeBag = DisposeBag()

This creates a DisposeBag you’ll use to ensure that the Observers you set up will be cleaned up when deinit() is called.

Add the following under the //MARK: Rx Setup comment:

//MARK: Rx Setup

private func setupCartObserver() {
  //1
  ShoppingCart.sharedCart.chocolates.asObservable()
    .subscribe(onNext: { //2
      chocolates in
      self.cartButton.title = "\(chocolates.count) \u{1f36b}"
    })
    .addDisposableTo(disposeBag) //3
}

This sets up a reactive Observer to update the cart automatically. As you can see, RxSwift makes heavy use of chained functions, meaning that each function takes the result of the previous function.

How that’s happening in this case:

  1. First, you grab the shopping cart’s chocolates variable as an Observable.
  2. You call subscribe(onNext:) on that Observable in order to find out about changes to the Observable’s value. subscribe(onNext:) accepts a closure that will be executed every time the value changes. The incoming parameter to the closure is the new value of your Observable, and you’ll keep getting these notifications until you either unsubscribe or your subscription is disposed. What you get back from this method is an Observer conforming to Disposable.
  3. You add the Observer from the previous step to your disposeBag to ensure that your subscription is disposed of when the subscribing object is deallocated.

To finish up, delete the imperative updateCartButton() method. This will cause errors to appear where it was being called in viewWillAppear(_:) and tableView(_:didSelectRowAt:).

To fix them, delete the entire viewWillAppear(_:) method (since calling updateCartButton() is the only thing it’s doing beyond calling super), then delete the call to updateCartButton() in tableView(_:didSelectRowAt:).

Build and run. You’ll see the list of chocolates.

But notice that the button for the cart just says “Item”. And that when you start tapping on the list of chocolates, nothing happens. What went wrong?

You created a function to set up your Rx Observers, but right now there’s nothing actually calling that function, so the Observers aren’t being set up. To fix this, add the following to viewDidLoad():

setupCartObserver()

Build and run the application to see the list of chocolates again. Tap on some chocolates—the number of items in the cart now automatically updates!

Success! All the chocolates can now be added to the cart.

RxCocoa: Making the TableView Reactive

Now that you’ve made the cart reactive using RxSwift, you’ll use RxCocoa to make your UITableView reactive too.

RxCocoa has reactive APIs for several different types of UI element. These give you options to set up things like UITableViews without the need to override delegate or data source methods directly.

To demonstrate how this works, delete the entire UITableViewDataSource and UITableViewDelegate extensions and all of their methods. Next, delete the assignments to tableView.dataSource and tableView.delegate from viewDidLoad().

Build and run the application, and you’ll see that your happy little table view full of chocolates has suddenly become quite sad and empty.

That’s no fun. Time to restore the chocolates!

First, in order to have a reactive table view, you need something for the table view to react to. Still in ChocolatesOfTheWorldViewController.swift, update the europeanChocolates property to be an Observable:

let europeanChocolates = Observable.just(Chocolate.ofEurope)

The just(_:) method indicates that there won’t actually be any changes to the underlying value of the Observable, but that you still want to access it as an Observable value.

Note: Sometimes, calling just(_:) is an indication that using Reactive programming might be overkill—after all, if a value never changes, why use a programming technique designed to react to changes? In this example, you’re using it to set up reactions of table view cells which will change, but it’s always a good idea to look carefully at how you’re using Rx. Just because you have a hammer doesn’t mean every problem is a nail. :]

Now that you’ve made europeanChocolates an Observable, add the following:

private func setupCellConfiguration() {
  //1
  europeanChocolates
    .bindTo(tableView
      .rx //2
      .items(cellIdentifier: ChocolateCell.Identifier,
             cellType: ChocolateCell.self)) { // 3
        row, chocolate, cell in
        cell.configureWithChocolate(chocolate: chocolate) //4
      }
      .addDisposableTo(disposeBag) //5
}

What’s going on here:

  1. You call bindTo(_:) to associate the europeanChocolates observable with the code that should get executed for each row in the table view.
  2. By calling rx, you are able to access the RxCocoa extensions for whatever class you call it on – in this case, a UITableView.
  3. You call the Rx method items(cellIdentifier:cellType:), passing in the cell identifier and the class of the cell type you want to use. This allows the Rx framework to call the dequeuing methods that would normally be called if your table view still had its original delegates.
  4. You pass in a block to be executed for each new item. You’ll get back information about the row, the chocolate at that row, and the cell, making it super-easy to configure the cell.
  5. You take the Disposable returned by bindTo(_:) and add it to the disposeBag.

The values normally generated by tableView(_:numberOfRowsInSection:) and numberOfSections(in:) are now automatically calculated based on the data being observed. tableView(_:cellForRowAt:) is effectively replaced by the closure.

Go to viewDidLoad() and add a line calling your new setup method:

setupCellConfiguration()

Build and run the application, and voilà! Your chocolates have returned.

When you try to tap on each chocolate, however, they aren’t being added to the cart. Did you break something with your earlier Rx method?

Nope! By removing tableView(_:didSelectRowAt:), you’ve taken away anything which would recognize cell taps or know how to handle them.

To remedy this, there’s another extension method RxCocoa adds to UITableView called modelSelected(_:), which returns an Observable you can use to watch information about when model objects are selected.

Add the following method:

private func setupCellTapHandling() {
  tableView
    .rx
    .modelSelected(Chocolate.self) //1
    .subscribe(onNext: { //2
      chocolate in
      ShoppingCart.sharedCart.chocolates.value.append(chocolate) //3
      
      if let selectedRowIndexPath = self.tableView.indexPathForSelectedRow {
        self.tableView.deselectRow(at: selectedRowIndexPath, animated: true)
      } //4
    })
    .addDisposableTo(disposeBag) //5
}

Going through this step by step:

  1. You call the table view’s reactive extension’s modelSelected(_:) function, passing in the Chocolate model to get the proper type of item back. This returns an Observable.
  2. Taking that Observable, you call subscribe(onNext:), passing in a trailing closure of what should be done any time a model is selected (i.e., a cell is tapped).
  3. Within the trailing closure passed to subscribe(onNext:), you add the selected chocolate to the cart.
  4. Also in the closure, you make sure that the tapped row is deselected.
  5. subscribe(onNext:) returns a Disposable. You add that Disposable to the disposeBag.

Finally, go to viewDidLoad() and add a line calling your new setup method:

setupCellTapHandling()

Build and run. You’ll see your familiar list of chocolates.

But now you can add chocolates to your heart’s (or stomach’s) content!

RxSwift and Direct Text Input

Another useful feature of RxSwift is its ability to take and react to direct text input by the user.

To get a taste of handling text input reactively, you’ll add some simple validation and card type detection to the credit card entry form.

Credit card entry in non-reactive programs is handled by a tangle of UITextFieldDelegate methods, often with each one containing a mess of if/else statements indicating what actions and logic should be applied based on which text field is currently being edited.

Reactive programming ties the handling more directly to each input field, as well as clarifying what logic applies to which text field.

Go to BillingInfoViewController.swift. At the top of the class, add the following:

private let disposeBag = DisposeBag()

As before, this defines a DisposeBag to ensure all your Observables are properly disposed of when instances of your class are deallocated.

One thing that’s helpful to users putting in a credit card number is to display what type of credit card they’re inputting based on known card types.

To do this, add the following below the //MARK: - Rx Setup comment:

//MARK: - Rx Setup

private func setupCardImageDisplay() {
  cardType
    .asObservable()
    .subscribe(onNext: {
      cardType in
      self.creditCardImageView.image = cardType.image
    })
    .addDisposableTo(disposeBag)
}

In a moment, you’ll use this to update the card image based on changes to the card type. It adds an Observer to the value of a variable with a closure to execute when it changes, then makes sure that the Observer is properly disposed of in the disposeBag.

Now for the fun part: Text change handling.

Since a user might type quickly, you may not want to run your validation for every single key press. This can get very computationally expensive and lead to a laggy UI.

A good way around this is to debounce or throttle how quickly you’re putting the user’s input through a validation process. This means the input will only be validated at the throttle interval, rather than every single time it changes, so fast typing won’t grind your whole app to a halt.

Throttling is a particular specialty of RxSwift, since there’s often a fair amount of logic to be run when something changes. In this case, there’s not a crazy amount of logic, but there’s enough to make a small throttle worthwhile.

First, add the following just below the other property declarations in BillingInfoViewController:

private let throttleInterval = 0.1

This defines a constant for the throttle length in seconds.

Now add the following:

private func setupTextChangeHandling() {
  let creditCardValid = creditCardNumberTextField
    .rx
    .text //1
    .throttle(throttleInterval, scheduler: MainScheduler.instance) //2
    .map { self.validate(cardText: $0) } //3
    
  creditCardValid
    .subscribe(onNext: { self.creditCardNumberTextField.valid = $0 }) //4
    .addDisposableTo(disposeBag) //5
} 
Note: If you get a “Generic parameter R could not be inferred” compiler error when setting up creditCardValid, you can generally solve it by explicitly stating its type to silence the compiler, i.e. let creditCardValid: Observable. In theory, the compiler should be able to infer this, but sometimes it needs a little help. :]

What this code does:

  1. text is another RxCocoa extension (as indicated by having to call rx before being able to use it), this time to UITextField. It returns the contents of the text field as an Observable value.
  2. You throttle the input so that the validation you’re setting up is only run based on the interval defined above. The scheduler parameter is a more advanced concept, but the short version is that it’s tied to a thread. Since you want to keep everything on the main thread, use MainScheduler.
  3. You transform the throttled input by applying it to validate(cardText:), already provided for you by the class. If the card input is valid, the ultimate value of the boolean being observed will be true.
  4. You take the Observable value you’ve created and subscribe to it, updating the validity of the text field based on the incoming value.
  5. You add the resulting Disposable to the disposeBag.

Add the following code to the bottom of setupTextChangeHandling() to create Observable variables for the expiration date and card security code (a.k.a. the CVV):

let expirationValid = expirationDateTextField
  .rx
  .text
  .throttle(throttleInterval, scheduler: MainScheduler.instance)
  .map { self.validate(expirationDateText: $0) }
    
expirationValid
  .subscribe(onNext: { self.expirationDateTextField.valid = $0 })
  .addDisposableTo(disposeBag)
    
let cvvValid = cvvTextField
  .rx
  .text
  .map { self.validate(cvvText: $0) }
    
cvvValid
  .subscribe(onNext: { self.cvvTextField.valid = $0 })
  .addDisposableTo(disposeBag)

Now that you’ve got Observable values set up for the validity of the three text fields, add the following:

let everythingValid = Observable
  .combineLatest(creditCardValid, expirationValid, cvvValid) {
    $0 && $1 && $2 //All must be true
  }

everythingValid
  .bindTo(purchaseButton.rx.enabled)
  .addDisposableTo(disposeBag)

This uses Observable’s combineLatest(_:) method to take the three Observables you’ve already made and generate a fourth, called everythingValid, which is either true or false depending on whether all three inputs are valid.

everythingValid is then bound to the enabled property on UIButton’s reactive extension, so that the purchase button’s state is controlled by everythingValid’s value.

If all three fields are valid, the underlying value of everythingValid will be true. If not, the underlying value will be false. In either case, rx.enabled will cause the underlying value to be applied to the purchase button, which is only enabled when the credit card details are valid.

Now that you’ve created your setup methods, add the code to call them to viewDidLoad():

setupCardImageDisplay()
setupTextChangeHandling()

Build and run the application. To get to the credit card input, tap a chocolate to add it to the cart, then tap the cart button to go to the cart. As long as you have at least one chocolate in your cart, the checkout button should be enabled.

Tap the Checkout button, which will take you to the credit card input screen.

Type 4 into the Card Number text field—you’ll see the card image instantly change to Visa.

Delete the 4, and the card image will change back to unknown. Type in 55, and the image will change to MasterCard.

Neat! This app covers the four major types of credit cards in the United States (Visa, MasterCard, American Express and Discover). If you have one of those types of credit cards, you can input the number to see the correct image pop up and check to see if the number is valid.

Note: If you don’t have one of those credit cards, you can use one of the test card numbers that PayPal uses to test their card sandbox—these should pass all local validation in the application, even though the numbers themselves are not actually usable.

Once a valid credit card number is input with an expiration date (using a two-digit month and a four-digit year) anytime in the future and an appropriate-length CVV, the Buy Chocolate! button will enable.

Tap the button to see a summary of what you bought and how you paid for it, as well as a little easter egg:

Congratulations! Thanks to RxSwift and RxCocoa, you can buy as much chocolate as your dentist will let you get away with. :]

RxSwift and RxCocoa Introduction

Autoclosures And @autoclosure In Swift 3

What Is an Autoclosure

The first parameter of the fatalError(_:file:line:) function is an autoclosure as indicated by the @autoclosure keyword. But what is an autoclosure?

An autoclosure allows you to pass an expression to a function as an argument.

This definition should get us started. With this in mind, it makes sense that we can pass a string to the fatalError(_:file:line:) function. The string we pass to the function is an expression. The autoclosure wraps it in a closure. But why is that? What is the advantage of wrapping the expression in a closure?

By wrapping the expression in a closure, the function can decide if and when the closure is invoked. The moment the closure is invoked, the expression is evaluated.

As you can see, if used correctly, autoclosures are a powerful concept.

Anatomy of an Autoclosure

There are a few things you need to know about autoclosures. First, an autoclosure doesn’t take any parameters. Second, autoclosures usually return a value, but that isn’t always true. Later in this tutorial, we take a look at an example of an autoclosure that returns Void.

In Swift 3, closures are non-escaping by default. If the autoclosure of a function needs to be escaping, you need to prefix the @autoclosure attribute with the @escaping attribute.

When to Use Autoclosures

The benefit of autoclosures is that you don’t need to wrap the expression in curly braces. That is what you would need to do if you were to pass in a closure instead of an autoclosure.

In the below example, you can see that the fatalError(_:file:line:) function can accept an expression as its first argument thanks to autoclosures.

fatalError(response.error + " " + response.error)

Examples

Before I show you two examples of autoclosures, I need to emphasize that you won’t find yourself using autoclosures very often. This is a quote from The Swift Programming Language.

It’s common to call functions that take autoclosures, but it’s not common to implement that kind of function.

Despite the above quote, it is important that you understand the concept underlying autoclosures even though you won’t be implementing functions that use them very often.

Unbox

The first example I would like to show you is taken from one of my favorite libraries, Unbox, a lightweight JSON decoder created by John Sundell.

The following method is used to extract the value for a particular key or key path. What is important is that the method takes an autoclosure as its third parameter. The autoclosure returns the fallback value if no value for a particular key or key path is found.

func resolveRequiredValueForKey<R>(key: String, isKeyPath: Bool, fallbackValue: @autoclosure () -> R, transform: (T) -> R?) -> R {
    if let value = self.resolveOptionalValueForKey(key: key, isKeyPath: isKeyPath, transform: transform) {
        return value
    }
    
    self.unboxer.failForInvalidValue(invalidValue: self.unboxer.dictionary[key], forKey: key)
    
    return fallbackValue()
}

The implementation isn’t too complicated. What is of interest to us is the last line of the method.

return fallbackValue()

If no value was found, the autoclosure is invoked and the fallback value, which could be the result of an expression, is returned.

View Animations

The second example is a clever concept created by none other than Erica Sadun. In a blog post, Erica writes that autoclosures can help make the UIView API for animations easier and more elegant.

She wants to go from this:

UIView.animate(withDuration: 2.5) { 
    self.view.backgroundColor = .orange
}

To this:

UIView.animate(withDuration: 2.5, self.view.backgroundColor = .orange)

Notice that we don’t need to wrap the expression in a closure. How does this work?

To make this possible, we create an extension for UIView and implement a class method that accepts an autoclosure.

extension UIView {

    class func animate(withDuration duration: TimeInterval, _ animations: @escaping @autoclosure () -> Void) {
        UIView.animate(withDuration: duration, animations: animations)
    }

}

Remember that closure parameters, including autoclosures, are non-escaping by default. This means we need to prefix the @autoclosure attribute with the @escaping attribute.

What do you think? Doesn’t this look better?

UIView.animate(withDuration: 2.5, self.view.backgroundColor = .orange)

Should You Use Autoclosures

Apple emphasizes that autoclosures should not be overused. Not only is it hard to find valid use cases, autoclosures also make it harder to understand the program flow. Don’t overcomplicate your code with autoclosures if there is an easier alternative.

Autoclosures And @autoclosure In Swift 3

Dynamic Keyword in Swift 3

You probably know that the Swift language defines a number of attributes, such as objc, escaping, and available. It also defines a range of declaration modifiers.

As the name implies, a declaration modifier modifies a declaration. For example, by marking a class declaration with the final keyword, we inform the compiler that the class cannot be subclassed. This allows the compiler to make a number of optimizations to increase performance.

One other declaration modifier you may have come across is dynamic. In this tutorial, we explore what the meaning is of the dynamic declaration modifier and when you may want or need to use it.

Swift and Objective-C Interoperability

Even though Swift and Objective-C play well together, not every feature of Objective-C is available in Swift. Objective-C is a powerful language and much of that power is the result of the Objective-C runtime. Dynamic dispatch, for example, is one of the features that make Objective-C as dynamic as it is.

Dynamic what? Dynamic dispatch. It simply means that the Objective-C runtime decides at runtime which implementation of a particular method or function it needs to invoke. For example, if a subclass overrides a method of its superclass, dynamic dispatch figures out which implementation of the method needs to be invoked, that of the subclass or that of the parent class. This is a very powerful concept.

Swift uses the Swift runtime whenever possible. The result is that it can make a number of optimizations. While Objective-C solely relies on dynamic dispatch, Swift only opts for dynamic dispatch if it has no other choice. If the compiler can figure out at compile time which implementation of a method it needs to choose, it wins a few nanoseconds by opting out of dynamic dispatch.

Why Do I Need to Know This?

If you really want to understand what the dynamic declaration modifier means, then you need to understand the above.

How the Swift runtime works isn’t the topic of this tutorial. But you need to understand that the Swift runtime chooses other options, such as static and virtual dispatch, over dynamic dispatch whenever possible. It does this to increase performance.

Static and virtual dispatch are much faster than dynamic dispatch. Even though we are talking nanoseconds, the net result can be dramatic. If you are wondering, inlined access beats static and virtual dispatch hands down.

As you can imagine, bypassing dynamic dispatch has some drawbacks. Dynamic dispatch is one of the ingredients that make the Objective-C runtime as powerful as it is.

Right. But I am only using Swift in my project. Are you? The frameworks that power iOS, tvOS, macOS, and watchOS applications are written in Objective-C. And many features we have come accustomed to are only possible because of the dynamic Objective-C runtime, including Core Data and Key-Value Observing.

Dynamic Dispatch

This is a long explanation for a simple answer. By applying the dynamic declaration modifier to a member of a class, you tell the compiler that dynamic dispatch should be used to access that member.

By prefixing a declaration with the dynamic keyword, the declaration is implicitly marked with the objc attribute. The objc attribute makes the declaration available in Objective-C, which is a requirement for it to be dispatched by the Objective-C runtime.

You should now understand why the lengthy introduction was important for understanding the meaning of the dynamic keyword.

Classes Only

It goes without saying that the dynamic declaration modifier can only be used for members of a class. Structures and enumerations don’t support inheritance, which means the runtime doesn’t have to figure out which implementation it needs to use.

When to Use It

The dynamic declaration modifier is required whenever you need to make use of Objective-C’s dynamism.

Dynamic Keyword in Swift 3

@escaping, @available In Swift 3

In Swift 2, you may have run into the @noescape attribute. Have you ever taken the time to understand what it means? In Swift 3, @noescape has been removed from the language. Why is that? And why does Swift 3 introduce @escaping? Answering these questions is the focus of this article.

What Is the Meaning Of @noescape?

Even though @noescape is deprecated in Swift 3, it is useful to understand what it means. Why is that? The answer is simple. The @noescape attribute is applied by default in Swift 3. Let us start form the beginning.

What Is an Escaping Closure?

You first need to understand what an escaping closure is. The definition is very simple and easy to understand. If a closure is passed as an argument to a function and it is invoked after the function returns, the closure is escaping. It is also said that the closure argument escapes the function body. With this definition in mind, the name of the term escaping closure is well chosen. Right?

If a closure is passed as an argument to a function and it is invoked after the function returns, the closure is escaping.

In Swift 2, you could mark a function parameter with the @noescape attribute, telling the compiler that the closure passed to the function is not allowed to escape the function body. Take a look at the following example. Note that this example is written in Swift 2.

import HealthKit

class HealthKitManager: NSObject {

    private let healthStore = HKHealthStore()

    func requestAuthorization(completion: (Bool, NSError?) -> Void) {
        var shareTypes = Set<HKSampleType>()
        var readTypes = Set<HKSampleType>()

        // Add Workout Type
        shareTypes.insert(HKSampleType.workoutType())
        readTypes.insert(HKSampleType.workoutType())

        // Request Authorization
        healthStore.requestAuthorizationToShareTypes(shareTypes, readTypes: readTypes, completion: completion)
    }

}

You can see that the requestAuthorization(_:) function accepts one parameter, a closure. In Swift 2, closures can by default escape the function body and that is why the above example doesn’t cause the compiler any issues. Note that the completion parameter is passed as an argument to the requestAuthorizationToShareTypes(_:readTypes:completion:) method of HKHealthStore. This method is asynchronous, which means the closure is invoked after requestAuthorization(_:) returns. In other words, the closure we pass to requestAuthorization(_:) is escaping. It escapes the function body of requestAuthorization(_:).

Things become interesting if we add the @noescape attribute to the parameter of requestAuthorization(_:). This is what the example looks like with the @noescape attribute.

import HealthKit

class HealthKitManager: NSObject {

    private let healthStore = HKHealthStore()

    func requestAuthorization(@noescape completion: (Bool, NSError?) -> Void) {
        var shareTypes = Set<HKSampleType>()
        var readTypes = Set<HKSampleType>()

        // Add Workout Type
        shareTypes.insert(HKSampleType.workoutType())
        readTypes.insert(HKSampleType.workoutType())

        // Request Authorization
        healthStore.requestAuthorizationToShareTypes(shareTypes, readTypes: readTypes, completion: completion)
    }

}

We explicitly tell the compiler that the completion parameter should not be allowed to escape the function body. The result is that the compiler throws an error, explaining what is wrong.

Swift 3

Let me show you what the above example looks like in Swift 3. This will show you what has changed and what you need to know about escaping closures in Swift 3.

import HealthKit

class HealthKitManager: NSObject {

    private let healthStore = HKHealthStore()

    func requestAuthorization(@noescape completion: (Bool, Error?) -> Void) {
        var shareTypes = Set<HKSampleType>()
        var readTypes = Set<HKSampleType>()

        // Add Workout Type
        shareTypes.insert(HKSampleType.workoutType())
        readTypes.insert(HKSampleType.workoutType())

        // Request Authorization
        healthStore.requestAuthorization(toShare: shareTypes, read: readTypes, completion: completion)
    }
    
}

The compiler immediately informs us that @noescape is the default in Swift 3 and suggests to remove @noescape. In fact, @noescape is deprecated and you should no longer use it in Swift 3.

Because the closure we pass to requestAuthorization(completion:) (note that the method signature is different in Swift 3) is escaping, we need to mark the parameter as escaping. We use a new attribute for this, @escaping. This is a direct result of SE–0103, a Swift evolution proposal that proposes to make non-escaping closures the default. This is a very welcome change if you ask me.

import HealthKit

class HealthKitManager: NSObject {

    private let healthStore = HKHealthStore()

    func requestAuthorization(completion: @escaping (Bool, Error?) -> Void) {
        var shareTypes = Set<HKSampleType>()
        var readTypes = Set<HKSampleType>()

        // Add Workout Type
        shareTypes.insert(HKSampleType.workoutType())
        readTypes.insert(HKSampleType.workoutType())

        // Request Authorization
        healthStore.requestAuthorization(toShare: shareTypes, read: readTypes, completion: completion)
    }
    
}

You may have noticed that the @escaping attribute precedes the type of the parameter, not the name. This too is new in Swift 3.

What Is the Meaning of @escaping?

This brings us to the meaning of the @escaping attribute. Because closures are by default non-escaping in Swift 3, escaping closures need to be marked as such. And the @escaping attribute lets us do that.

The error of the compiler disappears by marking the closure as escaping, using the @escaping attribute.

Why Is This Important?

There are several benefits to make closures non-escaping by default. The most obvious benefits are performance and the ability for the compiler to optimize your code. If the compiler knows that a closure is non-escaping, it can take care of many of the nitty-gritty details of memory management.

This also means that you can use the self keyword without issues in non-escaping closures because the closure is invoked before the function returns. There is no need to use a weak reference to self in the closure. This is a nice benefit you get for free.

@AVAILABLE

In iOS 8, Apple changed the APIs for working with notification settings. If you are working on an application that supports an earlier version of iOS, then you are forced to use the deprecated APIs for registering for remote notifications. Fortunately, Swift makes this easy and safe.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if #available(iOS 8.0, *) {
        // Create User Notification Settings
        let userNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)

        // Register User Notification Settings
        application.registerUserNotificationSettings(userNotificationSettings)

    } else {
        // Register for Remote Notification Type
        application.registerForRemoteNotifications(matching: [.alert, .badge, .sound])
    }

    return true
}

The syntax is clear and concise. You use #available followed by a comma separated list of platform names and versions. The asterisk at the end of the list is required. It is a placeholder for future platforms.

How You Can Use It?

The availability syntax only works if the APIs you are using support it. Fortunately, it is easy to add support to your own libraries for the availability syntax.

In the example below, we use the @available attribute to indicate that the CircularView class is only available on iOS 8 and higher.

import UIKit

@available(iOS 8.0, *)
class CircularView: UIView {

    @available(iOS 8.0, *)
    func someMethod() {
        ...
    }

    @available(iOS 9.0, *)
    func anotherMethod() {
        ...
    }
    
}

You can use the @available attribute for any symbol, including classes, structures, enumerations, and methods. Nesting is important, though. For example, a method of a class cannot be more available than the class itself. In the above example, the compiler will throw an error if we set the availability of someMethod() to iOS 7.0.

At the time of writing, the availability syntax supports iOS, OS X, tvOS, and watchOS, including extensions for these platforms.

  • iOS
  • iOSApplicationExtension
  • OSX
  • OSXApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension
@escaping, @available In Swift 3