Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Mobile

Swift: Introduction to Apple's New Programming Language


The following line declares a divisibleBy10 function that receives an Int and returns a Bool indicating whether the received number is divisible by 10.

func divisibleBy10(number: Int) -> Bool {
    return number % 10 == 0
}

The following two lines declare an array of Int initialized with 9 numbers and call the applyFunction function with the array of Int and the divisibleBy10 function as the arguments. The divisibleBy10Numbers array of Int will have the following values after the applyFunction function runs: [10, 20, 30, 40, 50, 60].

var numbers = [10, 20, 30, 40, 50, 60, 63, 73, 43]
var divisibleBy10Numbers = applyFunction(numbers, divisibleBy10) 

For Loops

The previous lines showed simple examples of the use of arrays. If you want to declare an immutable array, you can use the let keyword, also known as a let introducer, when you declare the array. The applyFunction function used the following for loop to iterate through the elements of the array:

for item in list

The global enumerate function allows you to easily access both the index and the value for each item in an array. This function returns a tuple for each element composed by the index and the value. The following lines use this function to print the index and the value of the elements in the divisibleBy10Numbers array of Int.

for (index, value) in enumerate(divisibleBy10Numbers) {
    println("Item index #:\(index). Value: \(value)")
}

The use of (index, value) instead of a single variable name assigns the first element of the tuple to index, and the second one to value. The following lines would produce the same results by accessing the tuple elements with .0 and .1 for the first and second element:

for tuple in enumerate(divisibleBy10Numbers) {
    println("Item index #:\(tuple.0). Value: \(tuple.1)")
}

The following lines use a classic for loop to make the i variable go from 0 up to the number of elements in the array minus 1. The results are the same as with the previous two loops:

for var i = 0; i < divisibleBy10Numbers.count; i++ {
    println("Item index #:\(i). Value: \(divisibleBy10Numbers[i])")
}

The following lines use another syntax to make the i variable go from 0 up to the number of elements in the array minus 1:

for i in 0..<divisibleBy10Numbers.count {
    println("Item index #:\(i). Value: \(divisibleBy10Numbers[i])")
}

If you replace ..< with ..., the for loop increments the variable until it reaches the value specified after ... (inclusive instead of exclusive). The following lines produce the same results with ... instead of ..<.

for i in 0...divisibleBy10Numbers.count - 1 {
    println("Item index #:\(i). Value: \(divisibleBy10Numbers[i])")
}

Closures

As happens in most modern languages, Swift also supports closures. The following lines use a closure as an argument for the filter to generate the array with the numbers divisible by 10. The closure is the code surrounded with braces ({}). It uses the in keyword to separate the argument (number: Int) and the return type (Bool) from the body.

var divisibleBy10NumbersFiltered = numbers.filter({
    (number: Int) -> Bool in
    let result = number % 10 == 0
    return result
})

In this case, it is possible to omit the type for the closure's parameter and its return type. The following lines show a simplified version of the previously shown code that generates the same result. Notice that the closure code is really bare-bones and doesn't even include the return statement.

numbers.filter({
    number in number % 10 == 0
})

Tuples and Dictionaries

As you've seen, Swift supports tuples that group multiple values into a single compound value. The following lines define a returnPreviousAndNext function that receives an Int and returns a tuple with two Int values.

func returnPreviousAndNext(x: Int) -> (Int, Int) {
    return (x - 1, x + 1)
}

You can easily access the different elements of a tuple by adding a dot and the element number, starting with 0. For example, the following lines use .0 and .1 to display the previous and next values returned by the returnPreviousAndNext function.

var previousAndNext = returnPreviousAndNext(500)
println("The previous value is: \(previousAndNext.0)")
println("The next value is: \(previousAndNext.1)")

Swift allows you to easily decompose the contents of a tuple into either separate constants or variables. The following lines decompose the previousAndNext tuple into the previous and next constants, and then prints their values.

let (previous, next) = previousAndNext
println("The previous value is: \(previous)")
println("The next value is: \(next)")

You can also declare the names for the elements of the tuple in the returnPreviousAndNext function return type declaration. The following lines show a new version of the function that declares previous and next as the elements of the returning tuple.

func returnPreviousAndNext(x: Int) -> (previous: Int, next: Int) {
    return (x - 1, x + 1)
}

This way, you can easily add the following code to access the members of the tuple:

let previousAndNextTuple = returnPreviousAndNext(500)
println("The previous value is: \(previousAndNextTuple.previous)")
println("The next value is: \(previousAndNextTuple.next)")

The following lines declare a currencies dictionary with String key/value pairs.

var currencies = [
    "USD": "US Dollar",
    "EUR": "Euro",
    "CAD": "Canadian Dollar"
]

You can easily iterate through the dictionary key/value pairs by using a for loop (see Figure 2).

for (key, value) in currencies {
    println("Key: \(key), Value: \(value)")
}

Swift
Figure 2: The Playground allows you to evaluate the execution of loops.

Extensions

Extensions make it easy to add functionality to an existing type. The following lines add a toPoint3DInt method and a logText computed property to the Int type.

extension Int {
    func toPoint3DInt() -> Point3D<Int> {
        return Point3D<Int>(x: self, y: self, z: self)
    }
    var logText: String {
        return "Int value: \(self)"
    }
}

The following line creates a Point3D<Int> with x, y, and z set to 5 by using the toPoint3DInt extension method:

var point = 5.toPoint3DInt()
println(point.x)

The following line displays the contents of the logText computed property. The type inference makes number an Int.

var number = 7
println(7.logText)

Objective-C Factory Methods and Swift

Objective-C factory methods are mapped to initializers in Swift. Thus, the creation of instances of Objective-C API objects feels natural in Swift. For example, the following code shows an Objective-C line that initializes a UIColor.

UIColor *color = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];

The following line shows the equivalent code in Swift that initializes a UIColor:

let color = UIColor(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)

The Swift compiler includes support for attributes that make it possible to enable Interface Builder features for Swift:

  • Outlets: @IBOutlet.
  • Actions: @IBAction.
  • Live and interactive custom view design: @IBDesignable and @IBInspectable.

The project structure for iOS apps for Swift is similar to the one used for Objective-C. The only difference is the programming language — and that Swift doesn't use headers.

Conclusion

There are many other interesting features in Swift that you might want to consider, such as the powerful and extensible enumerations and structures, the versatile switch statement, and the protocols. After years of dealing with Objective-C and suffering from its painful syntax, I'm sure Swift is not the best language you will discover, but you will want to learn it to replace Objective-C.


Gastón Hillar is a senior contributing editor at Dr. Dobb's.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.