Update 8/5/14: Series updated for Xcode6-beta 5.
Swift is Apple’s brand new programming language, just released this year at WWDC.
Along with the language, Apple released an excellent Swift reference guide that I highly recommend.
However, the reference guide is long! So if you don’t have a lot of time and just want to learn Swift quickly, this Swift tutorial is for you.
This Swift tutorial will take around 15 minutes and will give you a quick tour of the Swift language, including variables, control flow, classes, best practices, and more.
You’ll even make a handy tip calculator along the way!
For this Swift tutorial, you will need the latest copy of Xcode (Xcode 6-Beta at the time of writing this Swift tutorial). You do not need any prior Swift or Objective-C experience, but it would help if you had some prior programming experience.
Important: Make sure you have the very latest copy of Xcode 6-Beta (check the iOS Developer Center to be sure). Swift is changing quickly and we are doing our best to update this tutorial as each beta comes out; the code may not work on older versions of Xcode 6-Beta.
Note: At the time of writing this tutorial, our understanding is we cannot post screenshots of Xcode 6 since it is still in beta. Therefore, we are suppressing screenshots in this Swift tutorial until we are sure it is OK.
Introduction to Playgrounds
Start up Xcode 6, and go to File\New\File. Select iOS\Source\Playground, and click Next.
Name the file SwiftTutorial.playground, click Next, and save the file somewhere convenient. Delete everything from your file so you start with a clean slate.
Note: After creating the playground, you may get an error that says “Error running playground: Failed to prepare for communication with playground”. If this happens, simply shut down Xcode and restart it again, and this error should go away.
A playground is a new type of file that allows you to test out Swift code, and see the results of each line in the sidebar. For example, add the following lines to your playground:
let tutorialTeam = 56 let editorialTeam = 23 let totalTeam = tutorialTeam + editorialTeam |
As you type these lines, you will see the result of each line on the sidebar. Handy, eh?
Playgrounds are a great way to learn about Swift (like you’re doing in this Swift tutorial), to experiment with new APIs, to prototype code or algorithms, or to visualize your drawing code. In the rest of this Swift tutorial, you will be working in this playground.
Note: At this point, I also recommend you drag your playground file (SwiftTutorial.playground) to your OS X Dock.
This way, you can use this file as a quick scratchpad whenever you want to test out some Swift code.
Variables vs. Constants in Swift
Try adding the following line to the bottom of your playground:
totalTeam += 1 |
You’ll notice an error when you add this line. This is because
totalTeam
is a constant, meaning its value can never change. You declare constants with the keyword let
.
You want
tutorialTeam
to be a variable instead — a value that can change — so you need to declare it with a different keyword: var
.
Replace the line that initializes
totalTeam
with the following:var totalTeam = tutorialTeam + editorialTeam |
Now it works! You may think to yourself, “why not just declare everything with
var
, since it’s less restrictive?”
Well, declaring things with
let
whenever possible is best practice, because that will allow the compiler to perform optimizations that it wouldn’t be able to do otherwise. So remember: prefer let
!Explicit vs. Inferred Typing
So far, you haven’t explicitly set any types for these constants and variables, because the compiler had enough information to infer it automatically.
For example, because you set
tutorialTeam
to 56
, the compiler knows 56 is an Int
, so it set the type oftutorialTeam
to an Int
for you automatically.
However, you can set the type explicitly if you want. Try this out by replacing the line that sets
tutorialTeam
to the following:let tutorialTeam: Int = 56 |
You may wonder if you should set types explicitly, or let the compiler infer the types for you. We believe it’s better practice to let the compiler infer types automatically where possible, because then you get one of the main advantages of Swift: concise and easy to read code.
Because of this, switch the line back to inferred typing:
let tutorialTeam = 56 |
Basic Types and Control Flow in Swift
So far, you’ve seen an example of Int, which is the Swift type that is used for integer values, but there’s a bunch more.
Floats and Doubles
let priceInferred = 19.99 let priceExplicit: Double = 19.99 |
There are two types for decimal point values like this:
Float
and Double
. Double
has more precision, and is the default for inferring decimal values. That means priceInferred is a Double
too.
Bools
let onSaleInferred = true let onSaleExplicit: Bool = false |
Note that in Swift you use true/false for boolean values (unlike the convention of using YES/NO in Objective-C).
Strings
let nameInferred = "Whoopie Cushion" let nameExplicit: String = "Whoopie Cushion" |
Strings are as you’d expect, except note that you no longer use the @ sign like you do in Objective-C. That might take your muscle memory a bit to get used to! :]
If statements and string interpolation
if onSaleInferred { println("\(nameInferred) on sale for \(priceInferred)!") } else { println("\(nameInferred) at regular price: \(priceInferred)!") } |
This is an example of an if statement, just like you’d expect in different languages. The parentheses around the condition are optional, and braces are required even for 1-line statements – w00t!
This also shows an example of a new technique called string interpolation. Whenever you want to substitute something in a string in Swift, simply use this syntax:
\(your expression)
.
At this point, you may wonder where the
println
output of this code has gone. To see the println output, bring up the Assistant Editor with View\Assistant Editor\Show Assistant Editor.
Here is the playground file up to this point in the tutorial.
Classes and Methods
One of the most common things you’ll be doing in Swift development is creating classes and methods, so let’s jump in right away!
First, delete everything in your playground file so you’re at a clean start.
Next, you’ll create a tip calculator class that will help you figure out what you should tip at a restaurant. You’ll add the code one small piece at a time, with explanations here each step along the way.
// 1 class TipCalculator { } |
To create a class, simply enter the
class
keyword and the name of your class. You then put two curly braces for the class body.
If you were subclassing another class, you would put a
:
and then the name of the class you are subclassing. Note that you do not necessarily need to subclass anything (unlike in Objective-C, where you must subclassNSObject
or something that derives from NSObject
).
Add this code inside the curly braces:
// 2 let total: Double let taxPct: Double let subtotal: Double |
This is how you create properties on a class – the same way as creating variables or constants. Here you create three constant properties – one for the bill’s total (post-tax), one for the tax percentage that was applied to the bill, and one for the bill’s subtotal (pre-tax).
Note that any properties you declare must be set to an initial value when you declare them, or in your initializer – otherwise you’ll have to declare them as optional (more on that in a future tutorial).
Note: According to the Emily Post Etipedia, tips should be pre-tax. That is why this class calculates the pre-tax amount before applying the tip!
Add this code after the previous block (inside the curly braces):
// 3 init(total:Double, taxPct:Double) { self.total = total self.taxPct = taxPct subtotal = total / (taxPct + 1) } |
This creates an initializer for the class that takes two parameters. Initializers are always named
init
in Swift – you can have more than one if you want, but they need to take different parameters.
Note that I have given the parameters of this method and the properties of this class the same names. Because of this, I need to distinguish between the two by putting the
self
prefix before the property names.
Note that since there is no name conflict for the
subtotal
property, you don’t need to add the self
keyword, because the compiler can automatically infer that. Pretty cool, huh?
Note: In case you’re wondering, here’s where the
subtotal = total / (tipPct + 1)
calculation comes from:(subtotal * taxPct) + subtotal = total subtotal * (taxPct + 1) = total subtotal = total / (taxPct + 1) |
Thanks to @chewbone for pointing this out!
Add this code after the previous block (inside the curly braces):
// 4 func calcTipWithTipPct(tipPct:Double) -> Double { return subtotal * tipPct } |
To declare a method, you use the func keyword. You then list the parameters (you must be explicit with the types), add the
->
symbol, and finally list the return type.
This is a function that determines the amount to tip, which is as simple as multiplying the subtotal by the tip percentage.
Add this code after the previous block (inside the curly braces):
// 5 func printPossibleTips() { println("15%: \(calcTipWithTipPct(0.15))") println("18%: \(calcTipWithTipPct(0.18))") println("20%: \(calcTipWithTipPct(0.20))") } |
This is a new method that prints out three possible tips.
Note that when you call a method on an instance of a class, the first parameter does not need to be named (but the rest do).
Also, notice how string interpolation isn’t limited to printing out variables. You can have all kinds of complicated method calls and operations right inline if you like!
Add this code to the bottom of the playground (after the curly braces):
// 6 let tipCalc = TipCalculator(total: 33.25, taxPct: 0.06) tipCalc.printPossibleTips() |
Finally, you create an instance of the tip calculator and call the method to print the possible tips.
Here’s what your playground file should look like at this point:
// 1 class TipCalculator { // 2 let total: Double let taxPct: Double let subtotal: Double // 3 init(total:Double, taxPct:Double) { self.total = total self.taxPct = taxPct subtotal = total / (taxPct + 1) } // 4 func calcTipWithTipPct(tipPct:Double) -> Double { return subtotal * tipPct } // 5 func printPossibleTips() { println("15%: \(calcTipWithTipPct(0.15))") println("18%: \(calcTipWithTipPct(0.18))") println("20%: \(calcTipWithTipPct(0.20))") } } // 6 let tipCalc = TipCalculator(total: 33.25, taxPct: 0.06) tipCalc.printPossibleTips() |
Check your Assistant Editor for the results.
Arrays and For Loops
Currently there is some duplication in the above code, because you’re calling the
calcTipWithTotal
method several times with different tip percentages. You could reduce the duplication here by using an array.
Replace the contents of
printPossibleTips
with the following:let possibleTipsInferred = [0.15, 0.18, 0.20] let possibleTipsExplicit:[Double] = [0.15, 0.18, 0.20] |
This shows an example of creating an array of doubles, with both inferred and explicit typing. Note that
[Double]
is just a shortcut for Array<Double>
.
Then add these lines underneath:
for possibleTip in possibleTipsInferred { println("\(possibleTip*100)%: \(calcTipWithTipPct(possibleTip))") } |
Enumerating through items in an array is similar to fast enumeration in Objective-C – note that there are no parentheses needed!
You could also have written this loop like this:
for i in 0..<possibleTipsInferred.count { let possibleTip = possibleTipsInferred[i] println("\(possibleTip*100)%: \(calcTipWithTipPct(possibleTip))") } |
The
..<
operator is a non-inclusive range operator and doesn’t include the upper bound value. There’s also a...
operator which is inclusive.
Arrays have a
count
property for the number of items in the array. You can also look up a particular item in an array with the arrayName[index]
syntax, like you see here.Dictionaries
Let’s make one last change to your tip calculator. Instead of simply printing out the tips, you can return a dictionary with the results instead. This would make it easier to display the results in some sort of user interface for the app.
Delete the
printPossibleTips
method and replace it with the following:// 1 func returnPossibleTips() -> [Int: Double] { let possibleTipsInferred = [0.15, 0.18, 0.20] let possibleTipsExplicit:[Double] = [0.15, 0.18, 0.20] // 2 var retval = Dictionary<Int, Double>() for possibleTip in possibleTipsInferred { let intPct = Int(possibleTip*100) // 3 retval[intPct] = calcTipWithTipPct(possibleTip) } return retval } |
Let’s go over this section by section:
- Here you mark the method as returning a dictionary, where the key is an Int (the tip percentage as an int, like 15 or 20), and the value is a Double (the calculated tip). Note that
[Int: Double]
is just a shortcut forDictionary<Int, Double>
. - This is how you create an empty dictionary. Note that since you are modifying this dictionary, you need to declare it as a variable (with var) rather than a constant (with let). Otherwise you will get a compile error.
- This is how you set an item in a dictionary. As you can see, it’s similar to the literal syntax in Objective-C.
Finally, modify the last line in your playground to call this method:
tipCalc.returnPossibleTips() |
Once the playground evaluates, you should see the results as a dictionary in the inspector (click the eyeball for an expanded view).
And that’s it – congratulations, you have a fully functional Tip Calculator in Swift!
Where To Go From Here?
Here is the final playground file with all the Swift code from this tutorial.
0 comments:
Post a Comment