Swift is Apple’s brand new programming language, just released this year at WWDC 2014.
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.
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.
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.
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 of tutorialTeam 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 MycodeTips {
}
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 subclass NSObject 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).
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
subtotal * taxPct) + subtotal = total
subtotal * (taxPct + 1) = total
subtotal = total / (taxPct + 1)
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 = MycodeTips(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 MycodeTips {
// 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 = MycodeTips(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.
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() -> Dictionary<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
}
Discover more from mycodetips
Subscribe to get the latest posts sent to your email.