Thursday, June 19, 2014

Advanced Swift - Part 1

This is a summary of the topics and notes that I found interesting from watching the Advanced Swift WWDC session 404 by John McCall and Dave Abrahams.  I highly recommend you watch the session.  It also has some commentary from me which you may or may not agree with.  Please feel free to join the conversation. :)

I have also attached a swift playground file with the sample code.

The Simple Thing Class

The first class the session introduced was the "Thing" class.  It's fairly basic, so I went ahead and completed its implementation. This was also the first time I realized that class initializes don't use the "func" keyword!  This is because initializers have some special characteristics that distinguish them from functions some of which is explored later on.

The location can be nil (no object) so it uses the "?" modifier.  We can easily create an instance of "Thing" using named parameters:

The simple Thing class is actually using a simplified version of argument names that make the caller's argument name equal to the name used by the initializer.  You can also create a version that uses the full argument names.

Full Argument Names

You can actually use the argument definitions full form to define argument names that allow the caller of the initializer to use a different name then what the initializer itself uses.

You can also do a condensed version of the arguments where the caller doesn't need to specify the argument name.  This is done through an anonymous wildcard expression.  Let's first take a look at these expressions to see how they work and then we will apply them to argument definitions.

Anonymous Wildcard Expressions (_)

Swift has the concept of an anonymous wildcard expression which is represented by an underscore (_). The wildcard expression can be used when you want to explicitly ignore a value during assignment. This comes in really handy when dealing with tuples.

You can apply the same technique to argument names.

Anonymous Argument Names

Instead of having explicit argument names you can specify anonymous argument names.  This should only be done in situations where the code becomes more readable/maintainable without the named parameters.

To me this is an example where Swift is giving too much flexibility in its expressiveness and is asking for abuse.


Protocols are like Objective-C protocols in that they don't provide an implementation.   Here is an example:

This example also introduced the difference between the === and the == operator.  The === means the objects must be the same instance where == just means they need to be equal but not necessarily the same instance.

Testing for Protocol Conformance

You can use a conditional cast to check if an object conforms to the protocol.  However, the example given in the session was incorrect.  When trying to compile it, I kept getting an error "cannot downcast from 'Thing' to non-@objc protocol type 'Pullable'".  According to the documentation under "Checking for Protocol Conformance” you can only test for protocol conformance of objective-c compatible protocols.   This makes the protocol only usable for class types which is fine in this case.  So making the adjustments to the protocol we can now implement a function that tests for conformance.

The example given also only specified the use of the "as" operator as opposed to "as?".  However, the documentation states that "as" will trigger a runtime error if it can't cast to the specified type so we need to use the "as?" operator to allow for cases when the object doesn't conform to the protocol.  So we had to use the "as?" operator as shown above.

Wrap Up

Lots of people are starting to learn Swift, including myself, so I hope this was helpful.  If you see anything incorrect or if you have different opinions please share your thoughts.

You can download the playground file which will allow you to play with and copy and paste all the code used.  Note that you will need XCode 6 to run the example.

Tod Cunningham
Five Lakes Studio, LLC

1 comment:

  1. Thanks for catching the issue with protocol. Adding the @objc saved me some grief.