How to protected your APIs

There has been much talk on the dev forums about the lack of protected in the Swift language. My personal opinion? I do not like the protected construct nor do I think it fits with Swift's other access modifiers as it would then be the only class-scoped access modifier.

Anyway, I have been playing around with how we can mimick one of the key desires: limiting the public API scope.

WARNING: This solution is very much an experiment to see if what it might be like. Do not take this as something you should do in your code. USE AT YOUR OWN RISK.

: .warning

Ok… the basic premise of the idea is this: subclasses should be able to have full access to a set of data within a class. However, we to make make it "hard" for general consumers of the API to use it.

public class Vehicle {
    // This is how we "hide" the API from the general user.
    public class Protected {
        public var numberOfAxles: Int = 0
        public init() {}
    }
    public private(set) var protected: Protected = Protected()

    public init() {}

    // All us to copy the protected state down the inheritance chain
    public init(protected: Protected) {
        self.protected = protected
    }

    // Our first addition to the inheritance model
    public var numberOfWheels: Int {
        assert(false, "This should really be abstract")
        return 0
    }
}

Alright, this is pretty straight-forward. I have created an inner class that presents the protected data for the vehicle and exposed all of that through a single, public member: protected. So we have "polluted" our public API with a single item instead of multiple and make it clear (by convention) that this is an unsafe area to be in.

Let's add some cars now:

public class Car : Vehicle {
    public class ProtectedCar : Vehicle.Protected {
        public var wheelSize: Int = 14
        public init() {
            super.init()
            self.numberOfAxles = 2
        }
    }

    public init() {
        super.init(protected: ProtectedCar())
    }

    override public var numberOfWheels: Int {
        return 4
    }

    public func wheelSize() -> Int {
        return (self.protected as ProtectedCar).wheelSize
    }
}

public class SportsCar : Car {
    public init() {
        super.init()
        (self.protected as ProtectedCar).wheelSize = 18
    }
}

The Car class has some additional protected data, so I created another inner-class that inherits from Vehicle.Protected. I also created a true public API that retrieves some of that inner data: wheelSize().

And here are the test cases to see it in action:

func testCar() {
    let car = Car()
    XCTAssertEqual(car.protected.numberOfAxles, 2)
    XCTAssertEqual(car.numberOfWheels, 4)
    XCTAssertEqual(car.wheelSize(), 14)
}

func testSportsCar() {
    let car = SportsCar()
    XCTAssertEqual(car.protected.numberOfAxles, 2)
    XCTAssertEqual(car.numberOfWheels, 4)
    XCTAssertEqual(car.wheelSize(), 18)
}

func testSportsCarAsCar() {
    let car: Car = SportsCar()
    XCTAssertEqual(car.protected.numberOfAxles, 2)
    XCTAssertEqual(car.numberOfWheels, 4)
    XCTAssertEqual(car.wheelSize(), 18)
}

func testSportsCarAsCarToFunction() {
    func inner(car: Car) {
        XCTAssertEqual(car.protected.numberOfAxles, 2)
        XCTAssertEqual(car.numberOfWheels, 4)
        XCTAssertEqual(car.wheelSize(), 18)
    }

    let car: Car = SportsCar()
    inner(car)
}

func testSportsCarAsVehicleToFunction() {
    func inner(vehicle: Vehicle) {
        XCTAssertEqual(vehicle.protected.numberOfAxles, 2)
        XCTAssertEqual(vehicle.numberOfWheels, 4)
    }

    let car = SportsCar()
    inner(car)
}

If you are of the mindset that the protected construct is one that is rare and really is about setting boundaries for your developers to not accidently call your APIs that are really not intended for non-subclass types, then this inner-type methodology might be OK for you.

Will I be using this pattern? Probably not. But, it is an initial experiment that I'm sure others may want to improve upon if the protected construct never comes and there is no other alternatives.

How to protected your APIs

Testing Privates (or rather, internals)

With Xcode 6, Beta 4, we saw the introduction of access modifiers (maybe a better name is visibility modifiers). In essense, they control the visibility of the member throughout the module and outside of the module.

Here they are:

  • private specifies an item that is available only within the context of the file
  • internal specifies an item that is available only within the context of the module (e.g. the compiled target)
  • public specifies an item that is available only both within the module and to all modules that import the given module

My personal opinion here… I'm not sure. I like the simplicity, but I think I'd simply rather have private and public. Seems Brent Simmons agrees. Time will tell, as will further Xcode 6 seeds.

The question naturally arrises: how do I test private methods?

Well, we have three basic options:

  1. You don't and only test their usage through public APIs 2. You need to expose them publicly 3. You need to add the source to your test project so that they are part of the module and make then internal

Option #3 is the way that I'm currently doing it. Is it the best way? Probably not, but it does have the following advantages:

  • We can selectively choose while files to add test coverage for
  • There is no duplication of code signatures to maintain
  • It works under both debug and ship builds
  • There is no impact to the public API surface

Getting Started

To get started, simply create a new project that contains both a Swift target and a Swift XCTest target.

Next up, create a new Swift file. I created one called Person.swift.

I'll use this dummy class implementation:

public class Person {
    private var firstName: String
    private var lastName: String

    init(_ firstName: String, _ lastName: String) {
        self.firstName = Person.ensureValidName(firstName)
        self.lastName = Person.ensureValidName(lastName)
    }

    internal class func ensureValidName(name: String) -> String {
        if countElements(name) == 0 {
            return "<invalid name>"
        }
        else {
            return name
        }
    }
}

In this contrived example, we want to validate the function ensureValidName without actually invoking the initializer. Why might we want to do this? Well, simple: this function could be used in many different places in the API. For instance, we could put this in the setter implementation for firstName and lastName.

In order to test this method, we need to actually add Person.swift as a compile target to the XCTest target as well. Once you do that, the following test case will be valid:

import Cocoa
import XCTest
class TestingInternalsTests: XCTestCase {
    func testInvalidNameWithEmptyString() {
        XCTAssertEqual(Person.ensureValidName(""), "<invalid name>")
    }

    func testInvalidNameWithNonEmptyString() {
        XCTAssertEqual(Person.ensureValidName("David"), "David")
    }
}

There are a couple of drawbacks that we get with this approach:

  1. We really are breaking the semantic rules here with respect to private and internal; there is no good reason that internal should be used for this function, except to expose it to tests. 2. We are compiling the Person.swift into the XCTest target; this could get messy as your project gets larger and larger.

As always, use with caution and with care. Hacks are hacks for a reason.

Testing Privates (or rather, internals)

Error Handling in Swift

Update, August 22nd, 2014: Please see Error Handling – Take Two for some updated insights. It may be the case that named tuples are the right approach to solve this problem.

: .info

Error handling is something that seems to be have been left to the coder to figure out for Swift. Yes, there is the overly clunky and terribly awkward NSError usage:

func contentsForType(typeName: String,
                        error: NSErrorPointer) -> AnyObject!
{
    // some code, oops! an error
    if error {
        error.memory = NSError(domain: domain,
                                 code: code,
                             userInfo: [:])
    }
    return nil
}

That is terrible. Not only do we need to use the NSError class and jump over into the ObjC runtime, for absolutely no good reason, we get to use a terrible syntax that is not how Swift even wants you to work. At the very least error could be an inout reference and we can do something nicer…

Well, I think we can do better: we can borrow from other languages! Haskell has a concept of an Either type that is essentially "either this value or that". That's pretty much want we want: "either our return value or an error". Great! Let's implement that and see how it feels in Swift.

Let's start out with some requirements:

  1. Need to support error information for function calls that have no return value
  2. Need to support error information for function calls that return a value
  3. Pure Swift implementation
  4. Names that clearly identify what we are working with

With those requirements, we know that we are going to need three different items:

  1. Error —  a type that represents the error information. This will simply be modelled after the NSError type

2 Failable  —  a type that represents either the error state or a success state with no return value

  1. FailableOf<T> —  a type that represents either the error state or a success state with a return value

The Error class is the easiest and most straight-forward:

struct Error {
  typealias ErrorInfoDictionary = Dictionary<String, Any>

  let code: Int
  let domain: String
  let userInfo: ErrorInfoDictionary

  init(code: Int, domain: String, userInfo: ErrorInfoDictionary?) {
    self.code = code
    self.domain = domain
    if let info = userInfo {
      self.userInfo = info
    }
    else {
      self.userInfo = [String:Any]()
    }
  }
}

There really is not much to say about the class: it is basically the Swift version of the NSError class from ObjC.

Now, to tackle the Failable type:

enum Failable {
  case Success
  case Failure(Error)

  init() {
    self = .Success
  }

  init(_ error: Error) {
    self = .Failure(error)
  }

  var failed: Bool {
    switch self {
    case .Failure(let error):
      return true

    default:
      return false
    }
  }

  var error: Error? {
    switch self {
    case .Failure(let error):
      return error

    default:
      return nil
    }
  }
}

An enum is the perfect choice for us because a Failable has exactly two states: Success and Failure. There are no other possibilites.

On top of that, we have some helper methods failed and error that prevent us from having to write this terrible code to get the values out each time:

switch result {
case .Failure(let error):
  // handle the error here

default:
 // no error, do something else
}

Instead, we can write much more natural code:

let result = failableMethod()
if result.failed {
  // handle the error
}
// continue on

I'm going to pause here. Some of you may be wondering, why not implement the LogicValue protocol? Great question! Because that protocol is the DEVIL!

if result {
 // handle the error?? or does this mean there is a result???
}
// continue on?

I find the protocol extremely ambiguous and error prone. That's why I'm not using it.

The FailableOf<T> is not that much different, other than a fairly annoying bug in Swift that cannot generate the correct code—more on that in a minute.

enum FailableOf<T> {
  case Success(FailableValueWrapper<T>)
  case Failure(Error)

  init(_ value: T) {
    self = .Success(FailableValueWrapper(value))
  }

  init(_ error: Error) {
    self = .Failure(error)
  }

  var failed: Bool { /* same as above … */ }
  var error: Error? { /* same as above … */ }

  var value: T? {
    switch self {
    case .Success(let wrapper):
      return wrapper.value

    default:
      return nil
    }
  }
}

There are a few changes:

  1. A value is stored for the Success state
  2. A new value property has been added
  3. There is this pesky FailableValueWrapper

There is a bug in Swift where the compiler cannot generate the code for an enum that does not have a fixed layout, which would be the case if the Success value could hold any old type of T. To get around this, we can create a wrapper class so that the FailableOf<T> can essentially use the class pointer size for laying about the enum. Hopefully this gets addressed in later drops.

That's basically it. Now we can handle errors in a much more Swift-friendly way. Below is some sample use case:

func failWhenNilAndReturn(name: String?) -> FailableOf<T> {
  // not using .Success because of the
  // FailableValueWrapper workaround.
  if let n = name { return FailabeOf<T>(n) }
  else { return .Failure(Error(code: 2,
                              domain: "err",
                            userInfo: nil)) }
}

let result = failWhenNilAndReturn("David")
if result.failed { /* handle the error */ }
println("name: \(result.value!)")

I'm not the first to write on this topic, nor will I be the last. This is definitely an odd area that was left out for Swift…

The full source code can be found in my SwiftLib project on GitHub: https://github.com/owensd/SwiftLib.

Error Handling in Swift

Swift Arrays are Fixed!

If you've been following along with Swift, you would have noticed some very interesting semantics with arrays: they were completely broken! Interestingly enough, there were many people arguing in the forums and other places that this was "ok" and "good for performance".

Fortunately for us, the Swift team decided on sanity. So instead of code like this working (Xcode 6, Beta 2):

let array = [5, 1, 0, 10]
array[1] = 0   // just changed a value in the "const" array, ok…
array += 5     // compile time error: good

var sortedArray = sort(array)   // original array updated, oops!
sortedArray.append(4)

sortedArray                     // prints: [0, 0, 5, 10, 4]
array                           // prints: [0, 0, 5, 10]

We can return to the world of sanity in Xcode 6, Beta 3:

let array = [5, 1, 0, 10]
array[1] = 0      // compile time error: good
array += 5        // compile time error: good

var sortedArray = [Int](array)
sortedArray.sort(<)
sortedArray.append(4)

sortedArray                // prints: [0, 1, 5, 10, 4]
array                      // prints: [5, 1, 0, 10]

Many late-nights of debugging arrays have just been saved. Now, all we need, is a way to express const on class types. =)

Swift Arrays are Fixed!