In 2008 Apple announced and released the iPhone SDK 2.0. This event started another revolution in software development, and a new breed of developer was born. They are now recognized as iOS developers.

Many of these developers had never used Objective-C before, and that was the first challenge Apple threw at them. Despite unfamiliar syntax and manual memory management, it was immensely successful, helping populate the App Store with tens of thousands of apps. Apple continually improved Objective-C with each release, adding blocks and literals, simplified memory management with automatic reference counting, and many other features indicative of a modern programming language.

And after 6 years improving and working on Objective-C, Apple decided to throw another challenge at developers. Once again, iOS developers will need to learn a new programming language: Swift. Swift removes the unsafe pointer management and introduces powerful new features, while maintaining interaction with both Objective-C and C.

Swift 1.0 is already a stable and strong development platform, which is sure to evolve in interesting ways over the coming years. It is a perfect moment to start exploring this new language as it is obviously the future of iOS development.

The purpose of this tutorial is to give Objective-C developers a quick overview of new Swift language features, helping you take the next step and begin adopting Swift in your everyday work. I will not spend too much time explaining Objective-C, and I will assume you are familiar with iOS development.

Swift changed the game for Objective-C iOS developers.

Trying out Swift vs. Objective-C

In order to start exploring Swift all you need to do is download XCode 6 from the App Store and create a playground to experiment. All examples mentioned in this article are done this way.

Apple’s Swift homepage is the best reference for learning Swift programming. You will find it to be invaluable, and until you are fully up to speed with Swift development I believe that you will come back here often.

Variables and Constants

Declaring a variable in Swift is done using the var keyword.

var x = 1
var s = "Hello"

You will notice that two variables x and s are of different types. x is an Integer, while s is a String. Swift is a type safe language, and it will deduce variable types from the assigned value. If you wish to make your code more readable you can optionally annotate the variable’s type:

var y: Int
y = 2

Constants are similar, but you declare them using let instead of var. The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.

let c1 = 1 // Constant known at compile time

var v = arc4random()
let c2 = v // Constant known only at run time 

As their name suggests, they are immutable, so the following code will cause a compile-time error.

let c = 1
c = 3        // error

Other types can also be declared as constant. For example, the following code declares an array as a constant, and if you attempt to modify any of the elements, the Swift compiler will report an error:

var arr2 = [4, 5, 6]
arr2[0] = 8
print (arr2)    // [8, 5, 6]

let arr = [1, 2, 3]
a[0] = 5    // error

Optionals

Constants need to be initialized when declaring them, and variables need to be initialized before use. So where’s the Objective-C nil equivalent? Swift introduces optional values. Optional values can have a value or be nil. If you take a look at the following code, you will notice that x was assigned an Optional value of 2014. This means that Swift compiler was aware that x might also be nil.

var s = "2014"
var x = s.toInt()
print(x)    // Optional(2014)

If you make a change in this code and assign the value "abc" to s, which cannot be converted to an Integer, you will notice that x is now anil.

var s = "abc"
var x = s.toInt()
print(x)    // nil

The return type of toInt() function is Int?, which is an optional Int. Let’s try to call a standard function on x:

var x = "2014".toInt()
print(x.successor()) // error

The compiler signals an error, since x is an optional and could potentially be nil. We have to test x first, and make sure that the successor function is invoked on a real number, and not a nil value:

var x = "2014".toInt()
if x != nil
{
  print(x!.successor())    // 2015
}

Note that we have to unwrap x by appending an exclamation mark (!). When we are sure that x contains a value, we can access it. Otherwise we will get a runtime error. We can also do what Swift calls optional binding, converting the optional into a non-optional variable

let x = "123".toInt()
if let y = x
{
  print(y)
}

The code in the if statement will only execute if x has a value, and assign it to y. Note that we don’t need to unwrap y, it’s type is not optional since we know x is not nil.

Check Apple’s Swift tutorial to read more details on optionals and nice features like optional chaining

String Interpolation

In Objective-C formatting strings is usually done with the stringWithFormat: method:

NSString *user = @"Gabriel";
int days = 3;
NSString *s = [NSString stringWithFormat:@"posted by %@ (%d days ago)", user, days];

Swift has a feature called string interpolation to do the same, but it is more compact and easier to read:

let user = "Gabriel"
let days = 3
let s = "posted by \(user) \(days) ago"

You can also use expressions:

let width = 2
let height = 3
let s = "Area for square with sides \(width) and \(height) is \(width*height)"

To learn more about Swift’s string interpolation and other new features, go here.

Functions

Function definition in Swift is different from C. A sample function definition is below:

func someFunction(s:String, i: Int) -> Bool
{
    ...    // code    
}

Swift functions are first-class types. This means that you can assign functions to variables, pass them as parameters to other functions, or make them return types:

func stringLength(s:String) -> Int
{
    return countElements(s)
}

func stringValue(s:String) -> Int
{
    if let x = s.toInt()
    {
        return x
    }
    return 0
}

func doSomething(f:String -> Int, s:String) -> Int
{
    return f(s).successor()
}

let f1 = stringLength
let f2 = stringValue

doSomething(f1, "123")    // 4
doSomething(f2, "123")    // 124

Again, Swift infers the types of f1 and f2 (String -> Int), although we could have defined them explicitly:

let f1:String -> Int = stringLength

Functions can also return other functions:

func compareGreaterThan(a: Int, b: Int) -> Bool
{
    return a > b
}

func compareLessThan(a: Int, b: Int) -> Bool
{
    return a < b
}

func comparator(greaterThan:Bool) -> (Int, Int) -> Bool
{
    if greaterThan
    {
        return compareGreaterThan
    }
    else
    {
        return compareLessThan
    }
}

let f = comparator(true)
println(f(5, 9))

A guide to functions in Swift can be found here.

Enumerations

Enumerations in Swift are much more powerful than in Objective-C. As Swift structs, they can have methods, and are passed by value:

enum MobileDevice : String
{
    case iPhone = "iPhone", Android = "Android", WP8 = "Windows Phone8", BB = "BlackBerry"

    func name() -> String
    {
        return self.toRaw()
    }
}
let m = MobileDevice.Android
print(m.name())    // "Android"

Unlike Objective-C, Swift enumerations can assign Strings, characters or floats as values for each member, besides integers. The convenient toRaw() method returns the value assigned to each member.

Enumerations can also be parameterized:

enum Location
{
    case Address(street:String, city:String)
    case LatLon(lat:Float, lon:Float)
    
    func description() -> String
    {
        switch self
        {
        case let .Address(street, city):
            return street + ", " + city
        case let .LatLon(lat, lon):
            return "(\(lat), \(lon))"
        }
    }
}

let loc1 = Location.Address(street: "2070 Fell St", city: "San Francisco")
let loc2 = Location.LatLon(lat: 23.117, lon: 45.899)
print(loc1.description())        // "2070 Fell St, San Francisco"
print(loc2.description())        // "(23.117, 45.988)"

More information about enumerations is available here.

Tuples

Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other.

let person = ("Gabriel", "Kirkpatrick")
print(person.0) // Gabriel

You can also name the individual tuple elements:

let person = (first: "Gabriel", last: "Kirkpatrick")
print(person.first)

Tuples are extremely convenient as return types for functions that need to return more than one value:

func intDivision(a: Int, b: Int) -> (quotient: Int, remainder: Int)
{
    return (a/b, a%b)
}
print(intDivision(11, 3))    // (3, 2)
let result = intDivision(15, 4)
print(result.remainder)    // 3

Unlike in Objective-C, Swift supports pattern matching in a switch statement:

let complex = (2.0, 1.1)    // real and imaginary parts

switch complex
{
    case (0, 0):
        println("Number is zero")
    case (_, 0):
        println("Number is real")
    default:
        println("Number is imaginary")
}

In the second case we don’t care about the real part of the number, so we use an _ to match anything. You can also check for additional conditions in each case. For that we need to bind the pattern values to constants:

let complex = (2.0, 1.1)

switch complex
{
    case (0, 0):
        println("Number is zero")
    case (let a, 0) where a > 0:
        println("Number is real and positive")
    case (let a, 0) where a < 0:
        println("Number is real and negative")
    case (0, let b) where b != 0:
        println("Number has only imaginary part")
    case let (a, b):
        println("Number is imaginary with distance \(a*a + b*b)")
}

Note how we need to bind only the values we are going to use in the comparison or in the case statement.

To read more about tuples, go here.

Classes and Structures

Unlike Objective-C, Swift does not require you to create separate interface and implementation files for custom classes and structures. As you learn Swift, you will learn to define a class or a structure in a single file, and the external interface to that class or structure is automatically made available for other code to use.

Defining Classes

Class definitions are very simple:

class Bottle
{
   var volume: Int = 1000
   
   func description() -> String
   {
       return "This bottle has \(volume) ml"
   }
}
let b = Bottle()
print(b.description())

As you can see, declaration and implementation are in the same file. Swift no longer uses header and implementation files. Let’s add a label to our example:

class Bottle
{
   var volume: Int = 1000
   var label:String
   
   func description() -> String
   {
       return "This bottle of \(label) has \(volume) ml"
   }
}

The compiler will complain because label is a non-optional variable and will not hold a value when a Bottle is instantiated. We need to add an initializer:

class Bottle
{
   var volume: Int = 1000
   var label:String
   
   init(label:String)
   {
       self.label = label
   }

   func description() -> String
   {
       return "This bottle of \(label) has \(volume) ml"
   }
}

Or, we could use Optional type for a property, which does not to be initialized. In the following example we made volume an Optional Integer:

class Bottle
{
   var volume: Int?
   var label:String
   
   init(label:String)
   {
       self.label = label
   }

   func description() -> String
   {
        if self.volume != nil
        {   
               return "This bottle of \(label) has \(volume!) ml"
           }
           else
           {
               return "A bootle of \(label)"
           }
   }
}

Structures

The Swift language also has structs, but they are much more flexible than in Objective-C. The following code tutorial defines a struct:

struct Seat
{
    var row: Int
    var letter:String
    
    init (row: Int, letter:String)
    {
        self.row = row
        self.letter = letter
    }
    
    func description() -> String
    {
        return "\(row)-\(letter)"
    }
}

Like classes in Swift, structures can have methods, properties, initializers, and conform to protocols. The main difference between classes and structures is that classes are passed by reference, while structs are passed by value.

This example demonstrates passing classes by reference:

let b = Bottle()
print(b.description())    // "b" bottle has 1000 ml

var b2 = b
b.volume = 750
print(b2.description())    // "b" and "b2" bottles have 750 ml

If we try similar case with struct, you will notice that variables are passed by value:

var s1 = Seat(row: 14, letter:"A")
var s2 = s1
s1.letter = "B"
print(s1.description())    // 14-B
print(s2.description())    // 14-A

When should we use struct and when should we use class? As in Objective-C and C, use structs when you need to group a few values, and expect them to be copied rather than referenced. For example, complex numbers, 2D or 3D points, or RGB colors.

An instance of a class is traditionally known as an object. However, Swift classes and structures are much closer in functionality than in other languages, and much functionality can apply to instances of either a class or a structure type. Because of this, the more general term used in Swift reference is instance, which applies to any of these two.

Learn the basics of Swift classes and structures here.

Properties

As we saw earlier, properties in Swift are declared with the var keyword inside a class or struct definition. We can also declare constants with a let statement.

struct FixedPointNumber
{
    var digits: Int
    let decimals: Int
}

var n = FixedPointNumber(digits: 12345, decimals: 2)
n.digits = 4567    // ok
n.decimals = 3     // error, decimals is a constant

Also keep in mind that class properties are strongly referenced, unless you prefix them with the weak keyword. However there are some subtleties with weak non-optional properties, so read the automatic reference counting chapter in Apple’s Swift guide.

Computed Properties

Computed properties do not actually store a value. Instead, they provide a getter and an optional setter to retrieve and set other properties and values indirectly.

The following code provides a sample of a computed value sign:

enum Sign
{
    case Positive
    case Negative
}

struct SomeNumber
{
    var number:Int
    var sign:Sign
    {
        get
        {
            if number < 0
            {
                return Sign.Negative
            }
            else
            {
                return Sign.Positive
            }
        }
        
        set (newSign)
        {
            if (newSign == Sign.Negative)
            {
                self.number = -abs(self.number)
            }
            else
            {
                self.number = abs(self.number)
            }
        }
    }
}

We can also define read-only properties by just implementing a getter:

struct SomeNumber
{
    var number:Int
    var isEven:Bool
    {
        get
        {
            return number % 2 == 0
        }
    }
}

In Objective-C, properties are usually backed by an instance variable, declared explicitly or automatically created by the compiler. In Swift, on the other hand, a property doesn’t have a corresponding instance variable. That is, the backing store of a property cannot be accessed directly. Suppose we have this in Objective-C

// .h
@interface OnlyInitialString : NSObject

@property(strong) NSString *string;

@end

// .m

@implementation OnlyInitialString

- (void)setString:(NSString *newString)
{
    if (newString.length > 0)
    {
        _string = [newString substringToIndex:1];
    }
    else
    {
        _string = @"";
    }
}

@end

Since, in Swift, computed properties don’t have a backing store, we need to do something like this:

class OnlyInitialString
{
    var initial:String = ""
    var string:String
    {
        set (newString)
        {
            if countElements(newString) > 0
            {
                self.initial = newString.substringToIndex(advance(newString.startIndex, 1))
            }
            else
            {
                self.initial = ""
            }
        }
        get
        {
            return self.initial
        }
    }
}

Properties are explained in more detail here

To Be Continued

There are many more important new things to learn about in Swift, like Generics, interaction with Objective-C libraries, closures, optional chaining, and operator overloading. A single tutorial cannot describe thoroughly a new language, but I have no doubt much more will be written about learning Swift programming. However, I believe that this quick read will help many Objective-C developers, who haven’t managed to find time and learn details of Swift language, get on track and let the Swift bird take them to a new heights.

About the author

Marco Mustapic, Belgium
member since January 3, 2013
Marco is a Senior iOS developer specializing in game development with a particular affinity for coding conceptually original apps. He has coded extensively using Objective-C, and is proficient in designing architecture, algorithmic and performance problems, and slick UI effects and customization. [click to continue...]
Hiring? Meet the Top 10 Freelance Swift Developers for Hire in September 2016

Comments

brianm101
Nice article! But why does Apple go out of its way to make life difficult with another darn language. Why not stick with Java syntax or in even a version of c++ - keep just the good bits if you have to! But a new language - life is short enough without wasting it on another wannabe language!
Andrew
Shouldn't you unwrap **volume** or use optional chaining in the example?: if self.volume != nil { return "This bottle of \(label) has \(volume) ml" } should it be: volume!
Serge Zinin
No need to unwrap since he does not call anything on "volume" in a chain.
Marco Mustapic
Thanks! Fixed.
Sachin Palewar
Nice first article on Swift. Looking forward to next article.
Marco Mustapic
The need compatibility with all their and third party Obj-C libraries. A new version of C++ or a new version of Java is still a new language to learn.
Eric Allen
.toRaw() deprecated now, use property rawValue
Ome_Twi
Apple always does it - makes life more difficult (brakes old API) with every new major release of iOS! They started to invent wheel with Objective-C now they continue it with Swift. I mean, all this "new" features is just a combination(s) of already existed ones in old C/C++. What they really "invent" is notation. It's known long ago - cheaper to change wrapper than put a new stuff inside. Tons of codes already written in Objective-C and this code has to be maintained! Do they care? I guess not, same for the broken APIs with every new iOS.
Raghu Vallurupalli
crisp article , It helped a sixth grader to understand swift programming , try to come up with an article for GUI usage.
madan
its very helpful for me for understanding basics of swift.... thnx
kurisutofu
In "Functions", Shouldn't the below: doSomething(f1, "123") // 4 doSomething(f2, "123") // 124 be as below? doSomething(f1, "123") // 3 doSomething(f2, "123") // 123 If not, could you explain why? Thank you,
UnHoly
This post, and the one it's replying to are the types of mentalities you would have complained about growing up. You're preaching for stagnancy. This is technology, it is ever-changing, keep up or get off the train. When looking from an outside perspective at Swift vs. Obj-C I can easily see the discernible differences. First of all, Swift is much cleaner, and requires a lot less code to accomplish the same tasks. Swift throws away antiquated ways of writing code, and also is intelligent in the way that it interprets code. \ Ultimately, Objective-C is ~30+ years old, and while it has served us well, it is time to move forward. We live in a completely different world than we did in 1983, in all aspects of things, but especially from a technological standpoint. It makes perfect sense to re-write the language that we are using, as we are developing for technology that couldn't even be dreamed of in that time. In 15-20 years, we will be looking at another entirely new thing, written for the technology then, which will likely be completely different from now. Technology is like quantum mechanics, it does not move in a straight line, the line is everywhere, and constantly shifting, there is no telling how quickly or slowly things will advance. The only absolution is that things will indeed advance. Have a wonderful day folks.
iSwift
Well, I'm happy to say that I couldn't resist and created iSwift (started out as a Swift-related blog) but it now includes a fully featured an Objective-C to Swift converter. http://iswift.org It currently works online, as an independent OSX app and I'm also thinking of releasing it as a plugin for the Peppermint editor. So, here it is. Feel free to shoot me with lots of feedback - I'm all ears! :)
Anthony Dreyfus
Well, that's a great tool. Keep up the good work, guys! P.S. Any plans of complete Xcode project conversion?
iSwift
It sure is among my plans. But I'm taking the step-by-step approach. Let's first make it as good as possible and more... automated conversions will follow! :)
Geoff Angus
Indeed. OC has changed a LOT over the past few years, but it's less noticeable because it's been a steady change and it doesn't have a frightening, cool new name like "Swift". If, like me, you are just starting out in iOS development, it doesn't take long to realise that you're already getting a MUCH easier ride than those who were doing it in the beginning. A great example of this is ARC - I'm actually slightly alarmed by the fact that I didn't have to learn how to explicitly deallocate memory in OC because of it! In any case, I'm quickly realising that continuous learning and being a decent programmer are inseparable things.
Zam Light
var arr2 = [4, 5, 6] arr2[0] = 8 print (arr2) // [8, 5, 6] let arr = [1, 2, 3] a[0] = 5 // error <<< it should be arr[0] = 5 ?
Terry Torres
This was great!
comments powered by Disqus
Subscribe
The #1 Blog for Engineers
Get the latest content first.
No spam. Just great engineering and design posts.
The #1 Blog for Engineers
Get the latest content first.
Thank you for subscribing!
You can edit your subscription preferences here.
Trending articles
Relevant technologies
About the author
Marco Mustapic
Objective-C Developer
Marco is a Senior iOS developer specializing in game development with a particular affinity for coding conceptually original apps. He has coded extensively using Objective-C, and is proficient in designing architecture, algorithmic and performance problems, and slick UI effects and customization.