Access Control for Swift in Xcode Beta 4

 

Xcode Beta 4 introduces access controls to Swift, this is really important from a software architecture perspective because it allows us to properly implement encapsulation. Without the ability to hide members and methods of classes, it’s very easy to accidentally (or not) reach in to classes and mess with internals that were not designed to be directly modified.

Swift now offers three levels of access control: public, private, and internal.

public makes the entities visible anywhere within the module, or from other modules (as long as the module is imported)
internal makes the entities visible only within the same module. This is the default behavior as of the Swift version in Xcode Beta 4.
private makes the entities visible only within the same source file.

To demonstrate Swift’s new access controls, let’s build a small math class for Swift. For now, it’ll be really simple. It’s a class that has two properties of type Double, and has a single computed property named sum.

class QMath {
    
    var num1: Double?
    var num2: Double?
    
    var sum: Double {
        return num1+num2
    }
    
    init(_ num1: Double, _ num2: Double) {
        self.num1 = num1
        self.num2 = num2
    }
    
}

The class QMath has a constructor that takes two parameters, num1 and num2 of type Double. If you haven’t seen the underscores before, those are the external parameter names, which we’ve set to not be specified by using the underscore. If we instantiate a QMath instance in another class we can get the sum property and confirm it works as expected.

var m = QMath(4, 50)
println(m.sum)
54.0

You’ll notice that in our sum getter, we automatically assume that num1 and num2 are not nil. Although they’re both optionals, we can make this assumption if we know the init(,) method we’ve provided is called, because the arguments to that method are not optional and will definitely be set upon initialization.

Except one minor problem:
We could actually set either of those values to be nil.

var m = QMath(4, 50)
m.num1 = nil
println(m.sum)

This code compiles just fine, num1 is Optional and can be set to nil, not an issue. However, calling the sum getter now implicitly unwraps a nil optional. If you run this code you’ll see the following error:

fatal error: unexpectedly found nil while unwrapping an Optional value

We could simply set the num1 and num2 properties to not be optional, which would require we have a default value such as 0. But, an alternative method that allows us to avoid the unnecessary initial value is to simply disallow modifications to these internal variables. We want this class to be a black box, where num1 and num2 can’t directly be modified.

So, to solve our above mentioned encapsulation issue, we can make the two number properties private.

private var num1: Double?
private var num2: Double?

Attempting to build the app again now produces an error on the line we used to set num1 to nil.

m.num1 = nil
'QMath' does not have a member named 'num1'

Our external reference to the num1 property is no longer valid, it has no visibility to num1 and therefore this line of code is an error. There’s only one thing to do now, remove this line and start using the class as it was designed to be used! Mission accomplished!

If you want to dive deeper and tinker with Swift, it’s a good idea to read my post on Running Swift Scripts From The Command Line. When you’re ready to get serious make sure to also learn about my upcoming Swift eBook and video tutorial series.

Warning: Incoming opinion
Good software design principles suggest everything should be private by default, and entities should be exposed deliberately on an as-needed basis. This makes it easier to write more modular code and leads to cleaner programming interfaces. Disagree? Yell at me about it on Twitter.

Got a question or issue?

Join us on our new forums.

Sharing is caring :)

 
Follow me on Twitter
Developing iOS 8 Apps in Swift
An upcoming ebook detailing everything you need to know to produce marketable apps for iOS 8 using swift.
Learn to produce real world applications through tutorials. Available for pre-order today at a 25% discount.


Sign up now and get a set of FREE video tutorials on writing iOS apps when Xcode 6 is released.



Subscribe via RSS

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>