Thanks for joining us for an introduction to Swift.
Before we get started, I want to share you a little, a little fact.
So we announced Swift yesterday at the keynote and, as part of the announcement, we made available to you this document.
It's the Swift Programming Language.
It's the guide and reference to the language and it's available in the Doc Viewer online but also in the iBooks Store.
And something really remarkable happened.
From the time that we made it available yesterday we've had 370,000 downloads.
So, yes, thank you.
Anyway, this is "Introduction to Swift".
I am Tim Isted and I'm joined by Dave Addey.
This is the first of three talks on the Swift language this, at the conference, and we're focusing today on a broad overview of the language, giving you as much as we can, a few little teasers of some of the more advanced features.
Before we get started let's go back in time a little way, so many, many decades ago.
This program appeared and it printed "hello, world" for the first time.
It is, of course, the introduction to K&R, Kernighan and Ritchie's C book.
But many decades, that's quite a long time in computer terms.
So what's changed in that time?
Ahh. This becomes much shorter in Swift, yes, thank you.
So, what's happened in this time?
Well, we've got rid of the include statement.
There's no need to bring in the standard library.
It should just be there.
We should just be able to print and it should just work.
What about Main?
Well, this entire slide, this single line of code, that is a complete program right there and for something like this we shouldn't need to have to specify, you know, "This is the entry point for the app."
So we don't have to.
Because then it's not a function.
We're not returning any random values anymore and last, but not least, no semicolons.
So that's Hello World.
It's a very simple app.
It's a little bit simpler than what we all write day in, day out.
So, what are we going to cover today?
We're going to focus on syntax in some key areas: how Swift makes your code safe, makes it much easier to read, write, more concise, look at some of the modern features we've introduced and the consistency between declarations and all of the syntax that we have and, of course, how Swift gives you extra power to do things.
To kick us off I'm going to hand over to Dave Addey to take us through the basics.
So I'd like to start with some of the, the fundamentals of the Swift language.
Let's start with something really simple.
Let's define a variable.
So we do this with the var keyword and then the name, languageName in this case, and a colon and the type.
And this colon appears quite often in Swift.
This means, "is of type."
So languageName is a type string.
So we'll give it an initial string value to start us off.
Now I say initial value but there's one thing you might notice about this variable: it doesn't vary so there's no real need for this to be a variable.
Instead, we can define it as a constant with a let keyword instead.
And if we introduce a few more of these things, let's have the version of the language: that's a Double, 1.0.
We'll have the year it was introduced: that's an integer, 2014.
And the fact that the language isAwesome?
that's a boolean and clearly true.
Well, the year the language was introduced and the fact that it's awesome, these also aren't going to change.
So they may as well also be constant.
And this is a general principle in Swift, that we prefer immutability or constants by default and only really opt into mutability or variables where things actually need to change.
Now this makes your code safer in a multi-threaded environments.
It also means that Swift can optimize your code more effectively because it knows what isn't going to change and it just generally makes your code more readable, makes your intent clearer that you're saying what is and isn't going to vary.
So here I created a string, a double, an integer and a Boolean.
And it's pretty obvious from these values on the right-hand side what it is that I want to create.
In fact, it's so obvious from the values on the right hand side that there's really no point in me writing the types.
And in Swift, in many cases, you don't need to.
Swift uses type inference to look at the values on the right-hand side that we've assigned and work out what type these things should be.
Now this is, this makes code safe without the effort.
This means all these constants and variables are explicitly typed but you don't have to write a ton of code to get those types in place.
One more thing on constants and variables before we move on and that's that you can use pretty much any Unicode character you like for your constant and variable names, such as pi here.
And, yes, [applause] that does include emojis.
This is the stuff that matters, seriously [laughter].
So that's some of the basics.
Talking of Unicode we also have a modern, fast Unicode string implementation called, suitably enough, String and as we just saw if you're initializing a string from string literal, as we are here, Swift infers the times for you.
It's clear you want this to be a string.
Now, Swift's string syntax is very lightweight.
It looks a lot like a C string but it's as powerful as NSString and, indeed, if you're working with foundation you can use a Swift string anywhere you would use an NSString.
So here we're setting the HTTP method property of an NSURL request using a Swift string.
Moreover, if you're working with Foundation you have the entire NSString API available to you on any Swift string you create.
So we can call the pathComponents property on this string and get back an Array of the components therein.
Now every Swift string is a collection of characters and you can use a for-in loop to iterate over those characters such as here, we're printing the five characters in the word "mouse" on five lines.
This works just as well in English as it does in Icelandic or Russian or Chinese and even with emoji.
So if you want to create a character, you can do so just by assigning a character annotation to the string, the string literal that you've assigned.
This says we want this string, that we want this string literal to be a character not a string.
If you want to add together two characters you could do so just with addition and this goes for two characters making a string, it goes for strings and characters making longer strings, likewise 2 strings.
But sometimes we want to make more complex strings than just addition, so let's say we want to take these 2 constants, a and b, which are inferred to be integers from these default values of 3 and 5, and we'd like to make this string, "3 times 5 is 15" but in a way that would work for any values of a and b that we pass in.
Now Swift has a really elegant way to do this, a really powerful way of writing these kind of more complex strings, known as string interpolation and this is how it looks.
And we can insert constants and variables and even expressions such as "3 times 5" here directly within a string literal just by wrapping them in parentheses, escape with a backslash and it's really clear what this string interpolation will make when it's evaluated.
It makes exactly the string we'd expect.
And this works with any value of a and b.
Now you might be wondering does Swift have a mutable string type?
And the answer is actually it doesn't need one.
Instead, string mutability is a case of working with a variable, in which case the string can change, such as adding another string on the end or, alternatively, working with the constant in which case the string can't change.
It's actually a compile time error to try and add another string onto this constantString.
So that's string.
What else do we have?
Well, we have collection times, Array and Dictionary and, in the same way we saw, you can use a Swift string and an NSString interchangeably with APIs.
You can use an Array anywhere that takes an NSArray, and a Dictionary anywhere that takes an NSDictionary.
In fact, earlier on when we called the pathComponents property on our Swift string what we got back was actually an Array not an NSArray even though the API here is defined to return an NSArray.
Now the easiest way to create a new collection is with a literal and Array and Dictionary literals in Swift are very familiar from Objective-C.
Arrays are just square brackets around the edge, commas between the items.
Here we have an Array of four string values, four names.
Dictionary literals, also very familiar, colons between the keys and values, commas between the key value pairs, square brackets around the edge.
Here we have keys, which are strings, the names of some animals, and integer values, the numbers of legs that those animals have.
So these literals are very familiar but Array and Dictionary actually have 2 things that are quite different from NSArray and NSDictionary.
The first is they can work with any type.
Here we have strings and integers in our collections.
They don't have to be objects.
They don't have to be a Class type.
The second difference is that in Swift, collections are types collections.
Let's see what that means.
So here's our Array of names and it's an Array of four strings.
Now, it's pretty clear from looking at this Array of names that it would be odd to add an integer into this Array or, or a Boolean value, or a bicycle.
That would be just odd.
An Array of names should always be strings.
So it would be nice to have a way to say that it can only always be strings and in Swift we can.
We can provide a type annotation.
This is how we write an Array of strings.
String followed by two square brackets, and then we can only put strings in this Array.
But from the thing on the right-hand side here it's pretty clear that we want an Array of strings just from looking at this literal, and so if we initialize an Array in this way we actually don't need to write the type.
Swift can infer it for us and we still end up with a typed Array.
The same goes for dictionaries.
Here it's clear we want string keys, integer values, and Swift can infer this type for us as well.
This, the fact that we have typed collections makes code safe for two reasons.
Firstly, it means you know what you're going to get back.
You now what you'll get out of these collections.
It also means that you can't insert the wrong kinds of things by mistake.
It's actually an error to, to insert the wrong kinds of things into these Arrays and these Dictionaries.
So, having defined our collections, it would now be useful to loop over them, to iterate over their values.
And we have all the loops you'll be familiar with from C.
We have while loops, do while loops, and for loops.
And as we saw earlier, we also have the for-in loop, which we use with strings and characters but it's a bit more powerful than just strings.
We can use it for a few more things than that.
We can use it with ranges.
This is a way to write a range that includes the numbers at both ends.
Here it's 1...5.
That's known as a closed range because it includes both one and five in that range.
Here, we're just printing the first five items in the four times table.
Sometimes, however, we want to arrange the start at zero and count up to but not including the final value.
We have a way to write that as well, just using two dots rather than three.
So this counts from zero to five but not including five.
It's known as a half closed range.
It includes the value at the beginning but not the one at the end.
We can use for-in with an Array so to print a nice welcome to the four people in our names Array, and we can even use it with Dictionary.
Now note here that we're extracting the key and the value at the same time in a single for-in loop.
This makes for much more expressive code when working with dictionaries.
Now this combination of key and value wrapped together in parentheses is an example of a Swift feature known as a tuple.
And these are groupings of values grouped together as a single, compound value that you can pass around in your code.
And we'll come back to tuples later in the session to see where else they can be useful.
So that's how we create collections and how we iterate them.
How do we modify them?
Well, let's start with an Array.
Here's a shopping list, contains 2 items, eggs and milk.
As in Objective-C we can access the first item in the Array just using subscripting.
Here we're extracting eggs.
If we want to add an item to the Array, we literally just add it to the Array, we add it to the end.
Here we're adding a third item, flour.
We can also add multiple items in one go just by adding a compatible Array.
Here we're adding cheese, butter and chocolate spread to our list.
If we want to change a value subscripting again; we just assign a new value for an existing Array.
Here we're changing eggs to be six eggs.
And if we, if we want to make our shopping list a little bit healthier perhaps, we can actually replace an entire range in one go.
So we can replace items three through five, that's the cheese, the butter and the chocolate spread with some bananas and apples instead.
So that's, that's Arrays.
What about Dictionaries?
Well, we can modify.
Here's our Dictionary from earlier.
We have three key value pairs for animals and legs.
And so we start off with three but we want to add a new animal to this Array.
This is as easy as just assigning a new value for a key that's not already in the Dictionary.
Here we're adding the fact that spiders have 273 legs.
But there's a problem.
Spiders do not have 273 legs.
If you find one that does, run away [laughter] although be warned it will probably catch you.
But this is not a problem.
We can fix it.
We can just assign a new value for an existing key and change the value in the Dictionary.
Spiders now have eight legs.
So that's how to modify a Dictionary.
But what, what if we want to retrieve a value from this Dictionary?
What if we want to see if our Dictionary contains the number of legs for an aardvark, or perhaps the number of legs for a dugong, or maybe the number of legs for a Venezuelan poodle moth?
Well, our Dictionary might contain the number of legs for these animals but it might not.
There might be no value at all and we need a way to model this fact.
And this is a really good use case for a really powerful feature in Swift known as optionals.
I'd like to invite Tim back up to tell you more about optionals and some other power features that take us beyond the basics [applause].
Thank you, Dave.
So, I'd love to use Venezuelan poodle moths as my examples but I actually find that quite hard to say so I'm going to stick with aardvark.
How do we get the number of legs out?
Well, we can subscript and we can query this but what should we get back?
Well, we kind of want to be able to get two types of thing back.
We either want the number of legs as an integer or we want something that says this value wasn't found.
So, that's something else.
We could use some magic integer value like, I don't know, zero perhaps.
But the zero is a possible value here; snakes don't have any legs.
So we can't use zero.
In Objective-C you might be used to using things like NSNotFound or minus one and, you know, we could use minus one here.
As far as I know it's not possible to have minus one legs but we could be using an example where minus one was some kind of value we wanted back.
So wouldn't it be great if we could use some kind of value that didn't take up one of the possible integers?
In Swift we did this with an optional.
It's an optional integer, indicated here by "Int?"
It means that we either get an integer back or we get nothing at all.
So what does nothing at all mean?
Well, nothing in Swift is represented by nil.
It's very different to Objective-C nil, it means nothing.
It means no value at all in some optional value.
So we can test to see if this possible leg count is nil, to see whether the animal was found and if it is nil then the animal was not found.
What if it had been found?
How would we get this value out?
How do we get that integer out of the, out of the optional integer?
We would, we use that by, we do that by forcing the value out, using the unwrap operator.
That's the exclamation mark here.
So what I'm saying is I'm saying set the constant leg count to the underlying value inside possible leg count.
That's what that unwrap operator does.
Notice I'm not specifying a type of leg count here.
I don't need to because this is an optional Int.
The compiler knows that it's an optional Int and when I'm forcing that value out I get the underlying Int so leg count here is an integer.
Now I said forcing, forcing the value out when we're unwrapping it.
Why am I using that word?
Well, I am forcing the value out.
If I try and unwrap an optional and there's, in fact that there's no value there, it's nil, I'll trigger an assertion.
So I should only do this when I know for sure that the value is there.
Because of this, there's a very common pattern in Swift, which is to say, is there a value in this optional thing?
If there is, then unwrap it, give me the value back so I can use it.
So common, in fact, that we have a special syntax for this that's much safer.
It bundles those two steps into, into a single step.
And what this does is it says if possible leg count has a value, unwrap it, give it back to the leg count constant and then I can use it in the block of code.
If there is no value, block of code is skipped.
So we've seen a number of examples of if statements so far and if statements in Swift look much like they do in other languages.
There's one exception though and that is that there are no parentheses here.
We can use parentheses if we like, but they're actually optional.
So in this case they just add unnecessary punctuation noise so I'm going to leave them out.
The braces though, braces are required [applause].
And, as I can hear from that, you're acknowledging that this gets rid of a whole chain of bugs that happens with nested ifs, sorry trailing ifs.
That, you know, "if you have that" if statement and then two lines of code and you've indented them correctly but, uh, the second one is still going to happen.
It cannot happen in Swift, we have braces for that.
So we can do more complex things with if statements of course.
We can have an else if in there.
But in this case I'm matching, I'm matching multiple values.
I'm saying if leg count is zero then I'm printing on my animal slithers and slides around.
Otherwise, if it's one maybe it hops around.
Otherwise, it walks.
So I'm matching this, this leg count against multiple possible values.
Really I should be using switch.
Now switch in Swift-try saying that, saying that three times-is the most powerful of all of our control flow statements.
But let's start with the basics.
Starting with leg count, switching on that and I'm using case to indicate the possible values.
Value 0 slithers and slides; case 1, it hops; otherwise, it walks.
So use case like you do in C and Objective-C.
Notice I'm not specifying break here.
Cases in Swift do not automatically fall through.
I'm also not limited to just matching against integer values.
In Swift I can match against objects or read any values I like.
Imagine this is an ID action method and I'm tracking which, which object the user has interacted with.
So I can switch on the sender and match it against different outlets and print the suitable message.
So I can match an object.
Let's go back to integers for a moment.
And in Swift I can be much more expressive.
So here I'm matching multiple values in a single case at a time, of numbers between 1 and 13, animal limps, even numbers between 2 and 14, it walks.
That's nice, very expressive, but there's a problem with this example.
If I try and compile this, I'll get an error and the error says, "Switch must be exhaustive."
In Swift you must include a case or a default for every possible value that, that could be matched against.
So the easiest way to do that is to supply default case.
And the reason for this is it, again, makes your code safer.
Imagine you're writing something that uses a state machine and you have a big switch statement in the middle and you forget one of the cases.
Well, then your state machine grinds to a halt and that's bad.
That cannot happen in Swift.
You must have an exhaustive switch, which means either a case for every value or a default.
So we've matched against individual values here.
But, what if I might want to match against a lot of, a lot of values, a big range of values?
Well, I can do just that.
I can match against a range.
So this is bringing in pattern matching now a little bit.
So here we have zero still, no legs.
One to eight has a few legs and this is this closed range operator that Dave showed you earlier, includes both the one and the eight, three dots.
So that matches, has a few legs, otherwise lots of legs.
So that's an introduction to our pattern matching.
There's a whole load more awesomeness that you can find out about by watching the "Intermediate Swift" talk.
So, for the examples we've used so far we've seen a lot of println.
What is this thing?
This is a function, it's defined in the Standard Library, and it prints some value to the console.
How do we define our own functions?
When Swift functions are defined with the func keyword, so you can read this as declare a function called sayHello.
Doesn't take any parameters.
It doesn't return any values and in this case it prints "Hello" to the console.
Call it, as you might imagine, sayHello().
Of course, I can add a parameter.
Maybe I want to say hello to someone specific.
So I can add in a name parameter.
Notice the consistency here, name: String.
The name is of type string.
Matches with the variable declaration syntax and constants as well.
So this means I can now say, "Hello WWDC!"
Hello WWDC, and using string interpolation, I get my name in the, in the hello there.
In Swift, my parameter could have a default value as well.
So let's say I usually want to say, "Hello World."
I can add that with "=" so "name: string" and has a default value of "world".
This means I can call the function without specifying any name at all, it'll say, "Hello, World," but I still want to say hi to you guys, so, Hello WWDC, I can still do that anyway.
So that's parameters passing values into a function.
What about getting values out?
Well we return values in Swift with the arrow.
So here I've got a new function, it's called buildGreeting.
This time, it takes a name and it returns a string with a concatenation operator, that's that "+" there.
So function returns value with the arrow.
How do we get at that value?
I'm going to create a constant, it's called greeting, and I'm going to set it to the return value from this function.
Notice what I'm not doing.
I'm not specifying the type of greeting here.
It's very clear this returns a string because that's what the function returns.
The compiler knows that.
It will infer this correctly for us.
So we don't have to specify it again but we can supply the value right there to println and it just works.
We talked about returning a single value.
What about multiple values?
Well in Swift we can return multiple values with this tuple thing that Dave introduced earlier.
What is a tuple?
Well, tuple is just a grouping of, a grouping of values and they can be of any type and any number of values that you want, in this case, first tuple: three double values.
Otherwise, we could have an Int and a string, if I like, or Int and a string and a double-any combination of things that you like.
Why do I want one of these?
Well, it's not a replacement for a full-blown data Structure.
Sometimes you really want a Class or a Structure to be most explicit but tuples are really useful when you just want to pass multiple values around very simply, such as when returning multiple values from a function.
So in this example I have a refresh webpage function.
It goes out, refreshes a webpage and it gives me back the status code.
That means an integer code and a string message and they get bundled together.
So I return that with a tuple, (Int, String).
How do I get at those things?
How do I use them?
Let's create a constant.
This time I've got two names, also in parentheses with a comma in between and those get bound to the values that come back from a function.
This means that I can then use them individually and print them out separately.
So we've decomposed the tuple with these names.
Again notice, thank you, notice that I haven't specified types here.
Return of the function is obvious.
We've got two values coming back from there, they're an Int and a string.
So these map to the names and the compiler knows it's an Int and a message right there, I'm sorry, an Int and a string.
You've seen an example of this decomposition already.
That was when Dave was showing you enumeration of a Dictionary.
And the way that we give you the key and the value in one go is for each iteration through the Dictionary you get back a tuple pair containing the key and the value.
So these names here, these bind in to those returns and then you can use them individually in, in, in the full statement.
So tuple decomposition is one way to get these values out.
There's another one and that is we can actually name the values in the tuple.
So I've got this Int and a String but it's not entirely clear what they are.
What about if I could name them?
I'm going to say I have a code, which is a type Int, and a message, which is of type String.
Same syntaxes, parameters, and variable declarations.
Thing is of type, type.
This means, when I call this function, I can now just declare a single constant called status and I can then grab the individual bits out by name, status.code and status.message ready for use.
So that's functions.
I want to move to a related thing now which is Closures.
Closures in Swift, much like blocks in Objective-C.
They're just blocks of code.
You can pass them around, they can capture values from the surrounding scope.
So here I have a very simple one, it's called greetingPrinter and it's a constant, and it has this, this, this Closure that just prints, "Hello World!"
Again, I'm not specifying any type for greeting printer because it's very clear this Closure doesn't take any values.
It doesn't return anything either.
So the compiler will infer that this is this thing, () - ().
Empty parens are empty parens.
That's the type of this Closure.
It doesn't take any parameters.
It doesn't return any values.
You may think well that looks kind of familiar, I recommend this, this parens, arrow, parens syntax and that's because it looks very much like a function syntax and there's a reason for that.
In Swift functions are just named Closures.
So I can call my greetingPrinter thing just by saying greetingPrinter () and it prints, "Hello World."
That's a simple Closure as a local variable perhaps.
What about Closures as parameters?
Well to do this, same syntax again.
I'm going to create a repeat function this time and this will repeat a task a given number of times and the task is a Closure.
So, again, () - ().
Doesn't take any values, doesn't return anything, and it will be repeated for the number that I supplied.
How do I call it?
Let's call it twice.
I want this Closure to repeat, be repeated twice.
So I can supply my Closure inline right there in the function call.
Don't know about you, not so keen on that syntax.
And we can do something really special in Swift and that is if the Closure is the last argument to this function, we can shift it outside of the, outside of the parentheses of the function call and turn it into a Trailing Closure.
This makes the code much more readable.
It looks like a control close statement now, which it is in this case.
And, much more readable, much more modern bringing Trailer Closures in.
So that's Closures.
We've talked through functions.
We've talked through tuples.
To take us forward I'm going to hand back Dave to go through data types and specifically Classes [applause].
So let's take a look at how to define a Class in Swift.
We do this with the class keyword followed by the name of the class you want to create.
Here I'm going to create a vehicle.
And all of the class's definition, all of its implementation, appears between these curly braces, all of its properties, all of its methods, all of its initializers and we'll see how to write all of those in just a moment.
But first, there are two things you don't have to write in Swift.
You don't have to import vehicle.h and the reason is because Vehicle.h does not exist.
Swift doesn't have header files.
There's no need.
Instead, you just write your implementation for your class and that becomes its interface as well.
There's no need to duplicate it.
The second thing you don't have to write is we don't have to have a base class for Vehicle because Swift doesn't have a universal base class that every class must, must, must come from.
And you can still use NSObjects or any of the Cocoa or Cocoa Touch Classes if you wish, that's fine.
But you don't have to.
If it makes sense for vehicle to be a base class for some hierarchy of classes in your app then it can be.
It can be its own base class.
When we want to create a subclass ourselves we do this by providing the subclass name, followed again by a colon and then the thing we want to subclass from.
And we'll come back to this bicycle subclass shortly but first let's add a bit more detail to our base class, to our vehicle.
So we'll start by adding a property, a property called numberOfWheels.
It's a variable property, default value 0.
Know that this is exactly the same syntax we would use if we were declaring this as a variable, just move into class context.
Here we've made it be a variable property, what we'd call a read/write property in Objective-C but it could be a constant.
In this case, and we just use let, same as we would do for a normal constant.
But we'll keep it as a variable for now because we want to change its, change its value for some subclasses.
Now big, big difference that we have in Swift from Objective-C is that we don't have any distinction between instance variables and properties in Swift, they're one and the same thing.
And, in fact, this var numberOfWheels = 0 is all you have to write to define a property.
Swift provides the backing store for you.
You don't have to define it yourself and it handles all access to that backing store for you as well.
Now, in this case, were we just storing a value, these are known as stored properties but we do have a second kind of property as well-known as computed properties.
Let's add one of those to our Vehicle, our Vehicle class.
So this is a computed property that provides a description of our class, just a string description of the number of wheels it has.
Note that computed properties don't have a backing store.
Instead, they, they generate or calculate a value when they're called and to write one we provide the type that we want this property to have and then just return a value of the appropriate type.
Here we're using string interpolation to return the number of wheels.
Now, in this case I've provided a read-only computed property, which is why it only has a getter here, but I could also provide a setter as well if I wanted it to be read/write.
It doesn't really make sense for this description to be read/write though.
It's generated based on other properties so I'm going to keep it as a read-only property.
Where a computer property is read-only, you can actually lose the get and the braces and just return a value directly from the outer description of the computed property.
The end result is the same, you just don't have to write that extra level of nesting.
Note, however, that computed properties, even read-only ones, do need to be defined as variables.
Even though you can't set them, their value can change, it can vary, so they need to be variables.
Now that we've created our vehicle and we've given it a few properties, let's create a new instance of that vehicle, which we do with initializer syntax.
This is the name of the class followed by a pair of parentheses, creating a new instance of this class.
Because we provided a default value for our stored property, it's clear what to do when initializing this.
Just set numberOfWheels to 0.
Note that we didn't need to write alloc at the point that we created this instance.
Swift handles all of the memory allocation for you.
There's no need to write alloc.
We also didn't need to write the type.
Once again, Swift can infer the type we want to create.
It's clear from the thing on the right-hand side that we want this to be a vehicle.
As I mentioned earlier we, we have these default values.
Now, this means we actually haven't had to write an initializer at all because it's just clear what to do here.
It's clear to create a new instance, give it the default value of 0.
Now that we've created our vehicle instance we can use dot syntax to, to access its properties, so to print its description perhaps.
And we can see that it has a description of 0 wheels.
If we had changed them, the wheels to 2, we can see the description change.
It now has two wheels.
But it would be nice to create a class that always has two wheels by default, our bicycle subclass from earlier.
So let's see how we'd, how we do that, how we'd make it have two by default.
Now, because we want bicycle to change the value of an inherited property, we do need to write an initializer and this is how we do it.
The init keyword followed by a pair of parentheses and these can contain parameters so you can use parameters to customize your initialization, and they look just like the function parameters Tim showed earlier, but we're not going to use them in this case.
We're just going to use a new value of 2.
Now because we're changing an inherited property we do need to give our super class a chance to set that property first, which we do by calling super.init, after all it introduced the property so we need to give it a chance to set an initial value, which we may then use to modify the value we use.
After we've done so we can change the value, we can set it to 2.
Now we'll go into a lot more detail on initialization in the Intermediate Swift Talk but, for now, one final thing to note: Swift initializers don't return a value.
Rather, their main role is to make sure that every stored property has a value by the time its initialization completes.
So now we have that set up.
We can create a new bicycle.
We can print its description, which we inherited from vehicle, and see it has two wheels by default, all the, all bicycles have two wheels.
So that changes the default value of an inherited property but if we want to change its behavior?
What if we want it to do something different every time it's called?
For this we override the property.
We'll create a new subclass of vehicle called Car, give it a new stored property called speed, initial value of 0.0 (so inferred to be a double), and we'll add an initializer that sets the car's number of wheels to be four by default.
Same approach we just saw for, for the bicycle.
So its overrider description: in this case I'd like to add the speed on to the end of the description.
We just write the, we write the property in the same ways we did before.
So we have that same name and the same type.
But to do the override we have the override keywords on the beginning.
This makes the override safe for two reasons.
Firstly, it makes it clear we want to provide an override.
We haven't just accidentally written a property that has the same name and the same type of something in our super class that maybe we didn't even know about.
Moreover, it actually prompts Swift to go and check that this property exists somewhere in our super class chain so there definitely is something with the same name and the same type.
So our override will do what we expect.
In this case we'll just call the super description to get the number of wheels and we'll add an extra bit of text on the end that shows the speed.
So, if we create a car we can see that the description defaults to four wheels, zero miles per hour and, if we change the speed, it updates.
It now includes the new speed as well.
So that's the way to change the behavior of inherited property but maybe sometimes that's a bit overkill.
We don't want to see, we don't want to change how it works.
We just want to know when it changes and what it changes to and for this we have property observers.
So to show these, I'll create a subclass of car called ParentsCar.
Now, ParentsCar doesn't stop you going at a certain speed, it just watches how fast you're going and, if you go too fast, it issues a warning.
It says, "Careful now, that's a bit too fast."
[Laughter] So to do this we still override a property.
In this case we're overriding the speed property we inherited from Car.
Note that this override is for stored property, not a computer property, but it's still written in the same way.
This time, however, we won't provide a custom getter and setter, we'll provide either willSet or a didSet observer and willSet is called just before didSet just after the value changes.
WillSet gets a newValue constant that you can use within the body of the subserver.
didSet gets an oldValue constant so that you can see what the value was or has just changed to be within these observers.
In this case we'll just use willSet and we'll use that newValue constant to keep an eye on the speed of this car and if it goes over 65 miles an hour we'll issue a warning, careful now.
So that's how we add properties.
What about methods?
How do we add methods to our Classes?
Well, here's a simple class called Counter.
Just keeps track how many times something has happened.
Does with a stored property called count and in the same way that this stored property looks just like a variable, methods in Swift look just like functions, the ones that Tim introduced earlier.
Here, this increment method looks just like we'd write a function of the same type.
In this case it just adds 1 to count each times it's called.
If we make it a bit more complex, if we add a parameter, again, it's just the same as the function parameters we saw earlier.
Know that when we refer to count here, we don't have to use self.count inside the method because it's clear what we're referring to.
There's no ambiguity here.
The one time we do need to use self is if we have methods whose parameter name is the same as a property name.
Here we have a method with a parameter called count.
So in this case we use self.count to refer to the property and count refers to the parameter.
So that's how we create classes, how we give them properties, how we give them initializers and how we give them methods.
I'd now like to invite Tim back up to take us beyond classes and to show some of the other data structures you can create in Swift to make the building blocks of your apps.
Thank you [applause].
So beyond classes, where should we go next?
Let's go to structures.
Structures in Swift are defined using these struct keywords.
So here I'm going to define a couple, maybe three.
I've got a point, it has an x and a y coordinate, size with a width and a height, rectangle with an origin and a size.
With structures I get a very handy memberwise initializer by default.
This means it's really easy to create instances of these Structures just by supplying values for the properties in line.
So, supplying an x and a y, width and a height, point and a size for the rectangle.
If I really wanted to, I could actually provide custom initializers in my Structures.
To find out more about that check out the "Intermediate Swift" talk.
OK. So this is a simple structure.
It has an origin and it has a size.
Those are two, two properties.
It would be rather nice if I could add an area to my rectangle.
That sounds like a computed property so can we add one of those?
Yes, yes we can.
So here is an area property on my rectangle, just returns the width times the height.
OK, properties are great but what about methods?
Sometimes I want more than just a property.
Well, in Swift a structure can have a method as well.
So here I have an isBiggerThanRect(other: Rect) method and I can pass in a rectangle and return a value back that indicates whether it's bigger than the other one.
So structures in Swift, incredibly powerful, a lot more functionality than you're used to in C.
So that raises the question, what is the difference between a Structure and a Class?
Here's a couple of examples.
We've got a rectangle, that's at the moment a structure, and we've got a window.
It's a hypothetical Window class that refers to some user interface object.
How do you determine whether you want a class or a structure given that you've got a lot of the same functionality?
Where there are two primary differences between classes and structures.
The first difference is that structures cannot inherit from other structures.
The second difference is how values are passed around.
So let's look at our window.
I'm going to create a window; that means I get the window object.
All right, now this is a reference to that object.
But what if I declared my window as a structure?
Well, structures are passed by value.
That means the values are copied when they're passed around.
So my setup function here would get a copy of my window.
That seems weird.
What would happen?
Well, I'd probably get a second window on screen and that doesn't feel right at all.
So window, it should be a class because classes are passed by reference in Swift and that means my setup function gets a reference to the window that I gave it, it's a reference to this object.
OK, so that's classes.
What about structures?
Well, let's look at the frame of the window.
It's a rectangle.
And I want to get this frame, I want to do something to it, and I want to use it somewhere else.
So I'm going to extract it into a variable, newFrame.
What happens if rectangle was actually a class?
Well if I set the origin here, that's actually going to affect my window.
Clearly, that's not want I want to do.
I just want to change this and use it somewhere else and it's covering up my slide so, clearly bad.
So the window's frame is a rectangle and the rectangle, that should be a value type, a structure.
Structures are passed by value, they're copied around when they're passed around.
So we talked about the difference between reference and value types.
Let's look at constants and variables with these things in mind.
Let's say I create a window and this time I declare it with a let keyword, that means I have a constant window reference.
What does that really mean?
Well it means that I have a reference to a window object but the window object isn't affected by this constant.
It's only the reference that is.
So I can still change my window's title quite happily.
I can still set that to "Hello!"
and it just works.
But, it's a constant reference.
That means if I try and connect this reference to a different window I'll get a compile time error because I cannot mutate a constant and I'm trying to mutate the constant reference here.
What about value types?
Let's start with a variable.
I'm going to create a variable point1 and, for a value type, try to think of it as a big value in and of itself.
The whole thing is a value.
A point is an x and a y coordinate, so this point1 has an x and a y in there.
If I change my point1.x it's going to update that value and set it to 5 and that's fine, it's a variable, it can do that.
But if I use let to declare point2, the entire value is now immutable.
That's now constant.
That means I cannot set point2.x, the x coordinate there because I cannot mutate a constant.
The entirety of that value is constant.
Hmm. So, whether or not I can mutate my value type depends on the declaration used.
So what does that mean if I want to add some kind of a method to my Structure that, that changes it?
Let's say I want something that moves a point to the right by a given number.
Well, that's changing the value.
So I shouldn't be able to do this on a constant.
If you do want to do this then you must declare the method is mutating and it tells the compiler that you're changing the underlying value.
That means, if you declare a point with a constant in this case and you try and move it to the right you'll get an error because you cannot mutate a constant.
Structures, that's one example of a value type in Swift.
Another one is enumerations.
So enumerations in Swift can have raw values much like C.
So here I have a planet enumeration and it has a raw value of Int.
So I'm using a 1-based index.
Mercury is the first planet.
Venus is the second.
I could use 0 if I wanted but I want 1.
So Earth must have some, some value.
How do I determine what that value is?
Let's create a constant, EarthNumber, and I'm going to set it to raw value of Planet.Earth and that will give me back three.
That's how I get the raw value back out.
So I can use integers as an underlying value but in Swift I can use other types as well such as a string or maybe a character.
Here I can now name the tab, linefeed, and carriage return characters with using an enum.
But sometimes it doesn't make sense to have an underlying value at all.
Sometimes the cases are just values in their own right.
So here I have a compass point.
It has north, south, east and west.
There's no real number or string that really makes sense to tie to these so they're just values.
They're just values in themselves.
So how do I work with them?
Let's create a directionToHead.
It's a variable.
I'm going to maybe change that in the future.
And I'm going to set it to CompassPoint.West.
Compiler will then say oh, it's a compass point.
So it knows that directionToHead is a compass point.
Let's say I'm following some directions and I change direction, I want to head east.
How do I saw that?
Well, because the compiler knows that it's a compass point, all I have to say is enough to change that to east, which is .east in this example.
This works extremely well when you're working with Cocoa Touch and Cocoa.
We've done some incredible magic when we've imported things over into Swift, so that if you're dealing with a UILabel for example and you want to set the text alignment property, in Objective-C you do that with NSTextAlignment right.
But the compiler knows text alignment is NSTextAlignment, that is the type, so all we need to do is supply enough to specify that it is right.
So the text alignment is now right, much more readable, much more concise, super awesome.
Enums can have raw values, underlying values, no values at all but there's a different type I want to talk about and that's enumerations with associated values, neither are discriminated unions.
So to give you an example, let's consider a train.
Trains are usually one of two things, they're either on time, sometimes, or they're delayed.
If they're on time, they're just on time but, if they're delayed, they're delayed by a number of minutes.
So in this case we have (Int) after the delayed case.
And this says that I want to be able to, to catch both, either on time or the delay and the number of minutes that it's delayed.
Let's see how we work with that.
I'm going to create a status variable and I'm going to set it's initial value to TrainStatus.OnTime.
The train's very optimistic, he always starts on time but, as we all know, sometimes stuff happens and they get delayed and so we can change that just by saying, hey, it's now delayed and we can supply the value, 42 minutes, right there.
So that's an associated value.
Very powerful but we can, we can do more than this.
I'm going to add a little bit more functionality to my train status and I'm gonna start by adding an initializer.
This means that when I declare something that uses this train status it will automatically get the onTime status by default.
I'm not going to stop there though.
Let's add a computed property called description.
This time I'm going to determine what the value is and then give back a string that means something sensible.
So if it's on time it will say, "On time."
If it's delayed, I'm going to grab the number of minutes that it's delayed by by binding minutes in here to the number and then I can build a string using that with string interpolation.
So enumerations are hugely powerful here.
How do I work with this thing once I've done this?
Well, now I can delay, I can declare it with status = TrainStatus().
That'll give me an on-time status by default.
So if I print the description it will say it's on time but then it gets delayed, hmm.
And so I can set the delay and now when I call description it will give me "delayed by 42 minutes".
But this status is very much tied to a train.
It's very likely that the only place we really use this in our app is inside some kind of train class.
It seems a bit of shame to have it just floating around for anyone to use, or at least making it super easy for anyone to use.
Wouldn't it be nice if we could tie our status into the train class itself?
Well in Swift we can do that by nesting the type.
So we can grab, we can put our status inside the train class, nest it right there.
So now it's just called Status because it's inside the train.
Set up as before.
I can still have a property on my train that is of this, of this status and it will be set to OnTime by default and we can just use it.
So we can nest types in Swift.
Let's move on to more power.
I like power.
So an extension in Swift, very much like a category in Objective-C.
We can extend any Class we like.
But in Swift we can go a little bit further.
We can actually extend any named type we like, including value types.
So here I have my Size structure you saw earlier, that's a structure.
And I'm going to add this mutating function.
It increases the size by a given factor because it changes the underlying values I've marked as mutating.
But I'm not just limited to named types that I have in Swift.
I can actually also extend any name type I have available to me.
So here I'm extending CGSize, that's from Core Graphics.
It's a structure defined in C to add the same increaseByFactor.
When I've done that, it's available anywhere in my Swift code from this extension.
So that's extending a named type.
I want to see what else I can do with this.
Wouldn't it be fantastic if I could extend, hmm, an Int?
Well, yes it would and let's do that.
Int is just a structure defined in the standard library so I can extend it and I'm going to add a repetitions function to my integer and this is going to take a task, a closure, and it's going to repeat it to how, whatever value the integer is, 0..self, that will give me the number of repetitions I need.
So now I can supply closure on the call to repetitions on any integer value.
So I can say, for example, 500.repetitions and then supply closure and I'll get "Hello!"
printed 500 times [applause].
But there's more.
Because, because the closure is the last argument in this function call, I can hoist it out, put it outside of the parentheses and, you know what?
For training closures, if there are no other arguments I don't even need the parentheses.
So this turns into 500.repetitions do this thing like Control Flow.
So I just extended an Int, a value type Int from the Standard Library.
How amazing is that?
And as we head more into kind of blow your mind territory, I'm going to leave you with one more thing and that's generics.
So let's start with a non-generic example.
Here I have a stack of integers, it's an IntStack.
And I can push values onto the stack and I can pop them off again and that's, that's great but what if I wanted a double stack or a string stack?
Or, hell, even a stack of stacks?
How would I, how would I, how would I do that?
Well, I'd have to duplicate this definition multiple times and the only thing I would change would be these highlighted bits, the Ints across there.
That's the types used for the Array and the two functions that I have, the two methods.
Wouldn't it be lovely if I could just say, you know this, this should work with any type at all?
We can do that with a generic.
So generics in Swift, you indicate the type with these angle brackets and so
So elements is just an array of Ts.
Push now takes a T, pop now returns a T.
What does that mean?
It means that we can now build our stack of Ints like this.
We can just say create stack of Ints, push on 50, notice I'm not specifying anything and here the compiler knows that push must take an integer if it's a stack of Ints.
So I'm pushing 50 on.
I can pop that off and it knows that lastIn will be of type Int because that's what I'm dealing with.
What about strings?
Well, I can use this with a string as well, so now I can create a string of, uh, a stack of strings and push on a string, again, compiler knows it can only work with a string and when I pop it off it knows that I'm returning a string, therefore I can print it.
So that's generics.
It's a very, very brief introduction to generics.
To get further details on all of the awesome stuff you can do you should check out the "Advanced Swift" talk.
That brings me on to a question then.
How do you learn Swift?
How do you go and figure out all the cool stuff you can do with this language?
Well, as we saw up front, this book is available.
It's in the Doc Viewer, it's online.
It's available in the iBooks Store.
The Swift Programming Languages: it's the canonical guide and reference to the language.
We also have Using Swift with Cocoa and Objective-C.
This is a document that tells you how to work with Cocoa and Objective-C from existing code, how Swift interoperates with Cocoa.
For more information on the language itself, check out the intermediate and advanced Swift talks.
And for more information on Objective-C and interoperability, check out the two "Interoperability in Depth" and "Integrating Swift with Objective-C" talks.
We are in labs all week.
Come down, tell us what you think.
We want to hear your questions.
If you're playing along at home, talk to this guy, Dave DeLong.
He's our evangelist.
Check out Developer Forums.
Thank you very much.
That is Swift.
[ Applause ]