Introduction to the Swift Programming Language

Patrick Haralabidis
Tweet

One of the major and most surprising announcements to come out of Apple’s Worldwide Developers Conference was the introduction of Swift, a new programming language for Cocoa and Cocoa Touch.

Swift allows you to create native applications for iOS and OS X, and can be used in your existing projects alongside Objective-C. It promises increased performance and numerous modern features.

Here is a brief guide for getting started developing iOS applications with Swift today.

We will setup a development environment to work with Swift, look into the language fundamentals and compare the syntax side by side with Objective-C and other familiar languages such as JavaScript and C#.

At the end of this post we will create a simple but complete iOS application using Swift.

Setting up your environment

As with Objective-C you will require a current Mac and Xcode to develop with Swift.
At this stage version 6 of Xcode is still in beta, it can be downloaded now but you must be a member of the iOS or Mac Developer Program.

Log-in to the developer center and select the iOS 8 beta section, download Xcode from the Downloads section.

It is a rather large file, around 2.5 GB in size, so it may take a while. Once the download is completed, open the file and install the application by following the prompts. If you already have version 5 of Xcode installed it will remain unaffected as the beta version is installed as a separate application.

Go to the applications directory and launch Xcode 6.

Launch XCode

Accept the license agreement and wait for installation to complete.

That’s it, you are now ready to start exploring and developing with Swift.

Language fundamentals and syntax

Lets have a look at the language syntax and the differences with Objective-C and at the same time we will compare Swift with other modern languages.

As it is not possible to cover all aspects of Swift in depth in this article, we will cover the basics, using simple examples that demonstrate how tasks can be achieved at a high level.

If you would like to follow along, open Xcode 6, select “ Get started with a Playground” and type the Swift Code.

Welcome to Xcode

Alternatively you may download the code from GitHub and use it as a quick reference.

Variables and Constants

To declare a variable in Swift you use the keyword var

var number = 1

In other languages the same declaration looks like this:

Objective-C
int number = 1;

C#
var number = 1;

Javascript
var number = 1;

We can see how similar the Swift syntax is with other languages, the only difference is that we did not have to use a semi-colon at the end of the declaration.

The main difference with Objective-C is that we did not have to define the type, this is because Swift uses type inference and is able to understand that the type of the variable is a number because its initial value is a number.

However we are also able to define the type if we wish, like so:

var number: Int = 1

Lets declare a string variable in Swift:

var language = "Swift"

Here the declaration in Swift looks a lot cleaner and almost identical to C# and JS. How does this compare with Objective-C?

NSString *language = @"Swift";

There is no need to use memory pointers * and there is no need to prefix the string value with the @ symbol.

Moreover if you are working with foundation, you can use a Swift string in anyway that you would you use an NSString and you have access to the entire NSString API

Constants are also supported in Swift and can be declared using the keyword let

let language = "swift"

Or

let language: String = "Swift"

In other languages the same declaration looks like this:

Objective-C
NSString  *const language = @"Swift";

C#
const string language = Swift";

The advantage with Swift is that we can use type inference for constant declaration.

Working with variables in Swift is no different from other languages however it’s worth noting that it has an easy method for letting you add values in strings such as

var designers = 4
var developers = 4

var teamSize = "The team has \(designers + developers) members"

Arrays

In Swift you create arrays and dictionaries using brackets [ ] and access their elements by writing the index or key in brackets.

var arr = ["first" , "second"]

In other languages the same declaration looks like this:

Objective-C
NSArray *arr = @[@"first", @"second"];

C#
var arr = new[] { "first", "second" };

JS
var arr = ["first" , "second"];

You can get an item from the array using the index

var order = arr[0]

and set the value using

arr[0] = "third"

Syntax for the above tasks is the same in Javascript and C# with the addition of the semi-colon at the end of the statement.

Objective-C
NSString *order = arr[0];

You can enumerate the array using a for item loop

for item in arr {
    // do something
}

In other languages the same declaration looks like this:

Objective-C
for(NSString *item in arr)
{
    // do something
}

C#
foreach (var item in arr) {
    // do something
}

JS
for (index = 0; index < order.length; ++index) {
     //do something
}

To add another item to the array you can use the += operator

arr += "fourth"

Dictionaries

You can declare dictionaries in Swift by defining key-value pairs. When declaring an empty dictionary you have to define the type of the key and the type of the value.

var dict = Dictionary<String, String>()

You can declare and assign values

var dict = ["MEL": "Melbourne", "SYD": "Sydney"]

In other languages the same declaration looks like this:

Objective-C
NSDictionary *dict = @{
@"MEL" : @"Melbourne",
@"SYD" : @"Sydney"
};

C#
var dict = new Dictionary<string, string>
{
    { "MEL", "Melbourne" },
    { "SYD", "Sydney" }
};

To get an item from a Dictionary use

var entry = dict["MEL"]

In other languages the same declaration looks like this:

Objective-C
NSString *entry = dict[@"MEL"];
C#
var entry = dict["MEL"];

To set or add an item in the Dictionary use

dict["PER"] = "Perth"

In other languages the same declaration looks like this:

Objective-C
dict[@"PER"] = @"Perth"

C#
dict["PER"] = "Perth";

Finally to iterate over a dictionary you can use

for (cityCode, cityName) in dict {
    println("\(cityCode) : \(cityName)")
}

The cityCode variable contains the key and the cityName variable contains the value.

In other languages the same declaration looks like this:

Objective-C
for (id key in dict) {
    NSLog(@"key: %@, value: %@", key, dict[key]);
}

C#
foreach(var item in dict) {
    var cityCode = item.Key;
    var cityName = item.Value;
}

Loops

We’ve already seen how we can create a collection of items, lets have a look now at how we can loop through them.

Firstly, the for loop syntax.

for var number = 1; number < 5; number++ {
    //do something
}

As you would expect, you specify a value and increment until the condition is met. Objective-C and C# syntax is almost identical, JS is the same while omitting the type of the variable. You can refer to this document for a complete example.

You can achieve the same result by using the for in variant below:

for number in 1..5{
    //do something
}

Here Swift creates the number variable and assigns a value automatically while iterating over the specified value.

1..5 is a half-closed range that includes numbers from 1 to 4.

1…5 is a closed range that includes numbers from 1 to 5.

These ranges become very useful when you are working with arrays that are zero based.

Using the array we created earlier we could iterate over the cities using the syntax above.

for city in arr {
  println(city)
}

Swift also provides a while and do while loop that have the following syntax:

while number < 10
{
    println(number)
    number++
}

The variable after the while statement is a boolean and the code will execute when it evaluates to true.

The do while loop behaves the same way but it ensures that your code will be executed at least once before your condition is evaluated.

var number  = 9
do {
   println(number)
   number++
}
while number<10

In the example above we ensure that the number value is displayed before we increase it and evaluate the while statement.

Objective-C, C# and JavaScript syntax is almost identical, you may refer to this file for a complete example.

Conditionals

While loops control repetitive tasks in our code, we can use if and switch statements to control the flow in our code.

The if syntax in Swift can have parenthesis, but are optional, so you may use any style you prefer.

if city == "MEL" {
   println("Melbourne")
}

or

if (city == "MEL") {
    println("Melbourne")
}

if statements can be followed by else if and else

if city == "MEL" {
    println("Melbourne")
} else if city == "SYD" {
    println("Sydney")
} else {
    println("Perth")
}

Switch statements in Swift are followed by a case validation but a break statement is not required as there is no implicit fall-through. This means that once a case has been evaluated to true and executed the next case will not be evaluated.

The default action is however required.

switch city {
    case "MEL":
        println("Melbourne")
    case "SYD":
        println("Sydney")
    default:
        println("Perth")
}

The case can contain multiple values separated by a , or ranges.

As you can see, with Swift you can use NSString in a switch statement which is not possible with Objective-c.

Objective-C, C#, and JavaScript syntax is very similar, you may refer to this file for a complete example.

Functions

Functions are quite a large subject to cover within this article, but we should at least have a look at how we can declare and use them.

You can declare a function in Swift using the keyword func

func sayName() {
  println("Patrick")
}

Of course we can pass parameters within the parenthesis specifying a variable name and the type.

func sayName(name: String) {
  println(name)
}

Similarly we can pass multiple parameters separated by coma ,.

func sayName(name: String, lastName: String) {
  println("\(name) \(lastname)")
}

Finally we can declare functions that return results by adding an arrow -> after the parameters and specifying the return type.

func createName(name: String, lastName: String) -> String {
   return "\(name) \(lastname)"
}

Syntax Conclusion

Although we covered only the basics of the language above, it is evident that Swift provides a clean and modern syntax that is quite similar to other popular languages.
Objective-C developers will find a lot of similarities with the language and on top of the Objective-C functionality they can now enjoy features such as type inference, strong typing, no need for header files, generics and a lot more while creating iOS or Mac applications.

Creating an iOS application with Swift

Learning a new programming language is best achieved by writing code and creating applications, so lets create a simple iOS application using Swift.

We are going to going to connect to TheMovieDB API, request a list of upcoming movies, download the JSON results, parse them in to Dictionaries and Arrays and then populate our Table View with this information.

For the purpose of keeping this tutorial simple and to the point, we will cover common tasks such as creating and connecting UI elements to our code, working with multiple controllers, use delegates and protocols and of course demonstrate how to perform asynchronous operations with Swift, something that the language really excels at.

Before we get started you need to register and request an application API key from themoviedb.org website.

Sign up if you do not have an account already, then head into your account page and generate a new key from within the “API” section.

The code for the application we will create can be found on this GitHub repository, I have created branches for each stage.

Let’s get started.

Open Xcode 6 and create a new project, select a single view application under iOS and click on next

Single View App

Give the solution a name, I called mine UpcomingMovies , and select Swift as the language.

New Application

Click next and select a location where the project will be created.

Now lets create a table where we will display our data. Select the Main.storyboard file in Xcode and drag in a Table View object from the Object Library.

Insert Table

Now let’s connect our table to our code. We need to set up a delegate, a data source and an outlet.

Select the Storyboard file, hold control, and then click and drag from the tableview to the View Controller, select ‘data source’ in the popup menu. Repeat with the ‘delegate’ option.

Create a Delegate

To create the outlet, from the Xcode menu select view -> Assistant Editor -> Show assistant Editor. You will see a new section that displays the code from the ViewControler.Swift file.

Select the table and this time hold control, then click and drag from the tableview to the code window, release under the class declaration.

Give the outlet a name, I used appTableView, and click connect.

Create an Outlet

There is one final task left to complete our UI. We want to create a prototype cell that will contain the movie details text and will be re-used for every cell we create in our table.

To achieve this, select the Table View and in the attributes inspector, change the number of prototype cells to 1. Then click in to the cell, change the Style to Subtitle and type in the identifier as MovieResultsCell.

Create Prototype

Change Subtitle

That’s all the work required to complete our UI.

If this is the first time you have created an iOS application, I understand that all this clicking and dragging may sound confusing, but there are plenty of detailed instructions available to help you get started.

Alright, time to have some fun with Swift.

First we have to configure the datasource and dataset that we connected earlier in the storyboard.

In the ViewController file modify the class from this

class ViewController: UIViewController {

to this

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

Now we have to implement the 2 additional protocols we added above, so lets create the required methods.

Add the following lines of code to your file.

func tableView(tableView: UITableView!, numberOfRowsInSection     section: Int) -> Int {
    return 1
}

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    let cellIdentifier: String = "MovieResultsCell"

    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellIdentifier)

    cell.textLabel.text = "Test"
    cell.detailTextLabel.text = "test details"

    return cell
}

The first method is defining the number of rows in our table, the second method is responsible for displaying the data into our table and is where a lot of the work is completed.

Your ViewController.Swift code should look like this:

First phase of code overview

This completes phase 1, go ahead and run the solution, you should see the following result.

Example of App created so far

It’s time to connect to the API and retrieve the results. This code should be generic and reusable. The aim is to pass a Url as a parameter, get the result, parse the JSON and return an array with the data.

This code then can be used for subsequent API calls to other URls.

Create a new class by right clicking in the folder that contains your ViewController in the navigation pane and select New File .

Create a new file

Select Cocoa Touch Class, click on Next and give a meaningful name, I selected APIController, leave the default options as below.

Create API Class

Open the file and enter the following code underneath the import UIKit line.

protocol APIControllerProtocol {
    func JSONAPIResults(results: NSArray)
}

This defines a protocol that will be implemented in our ViewControler and will receive the results once the API call has completed.

Now lets add the function that will make the actual call and process the result. Within the class add the following code

var delegate:APIControllerProtocol?

func GetAPIResultsAsync(urlString:String) {

    //The Url that will be called
    var url = NSURL.URLWithString(urlString)
    //Create a request
    var request: NSURLRequest = NSURLRequest(URL: url)
    //Create a queue to hold the call
    var queue: NSOperationQueue = NSOperationQueue()

    // Sending Asynchronous request using NSURLConnection
    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{(response:NSURLResponse!, responseData:NSData!, error: NSError!) ->Void in
        var error: AutoreleasingUnsafePointer<NSError?> = nil
        //Serialize the JSON result into a dictionary
        let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(responseData, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary

        //If there is a result add the data into an array
        if jsonResult.count>0 &amp;&amp; jsonResult["results"].count > 0 {

            var results: NSArray = jsonResult["results"] as NSArray
            //Use the completion handler to pass the results
            self.delegate?.JSONAPIResults(results)

        } else {

            println(error)
        }
    })
}

I know that is a big chunk of code, we can’t go into detail here, however I have added comments to clarify what the code is performing.

This completes Phase 2, if you build and run you will see that this has made no difference yet.

It’s time to populate the data to our table. Open The ViewController.Swift file and add the APIControler delegate to the Class (it should now look like this).

 class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol {

Underneath the appTable outlet add the following 2 lines.

var searchResultsData: NSArray = []
var api: APIController = APIController()

The first variable will contain our table data. The second variable creates an instance of the API controller that can be used to call any of its methods.

Now implement the API controller protocol by adding the following method

func JSONAPIResults(results: NSArray) {
    dispatch_async(dispatch_get_main_queue(), {
        self.searchResultsData = results
        self.appTableView.reloadData()
        })
}

Lets change our tableView function and map the API data to our rows and cells.
Replace the following code

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    let cellIdentifier: String = "MovieResultsCell"

    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellIdentifier)

    cell.textLabel.text = "Test"
    cell.detailTextLabel.text = "test details"

    return cell
}

with this

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    let cellIdentifier: String = "MovieResultsCell"

    let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as UITableViewCell

    //Create a variable that will contain the result data array item for each row
    var cellData: NSDictionary = self.searchResultsData[indexPath.row] as NSDictionary
    //Assign and display the Title field
    cell.textLabel.text = cellData["title"] as String

    // Construct the posterUrl to get an image URL for the movie thumbnail
    var baseUrl: String = "http://image.tmdb.org/t/p/w300"
    var movieUrlString: String? = cellData["poster_path"] as? String
    var urlString: String? = "\(baseUrl)" + "\(movieUrlString)"
    var imgURL: NSURL = NSURL(string: urlString)

    // Download an NSData representation of the image at the URL
    var imgData: NSData = NSData(contentsOfURL: imgURL)
    cell.imageView.image = UIImage(data: imgData)

    // Get the release date string for display in the subtitle
    var releaseDate: String = cellData["release_date"] as String

    cell.detailTextLabel.text = releaseDate

    return cell
}

Going through the comments in the code above, you can see that we are assigning the values from the API to each cell, grabbing the movie title, the poster and the release date.

Replace the following function

func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
    return 1
}

with

func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
    return searchResultsData.count
}

This way we will create as many rows in our table as the results from our API. Now that our table cells are ready to receive the data, we can make the API call.

Add the following lines into the viewDidLoad method

//Construct the API URL that you want to call
    var APIkey: String = "" //Replace with your Api Key"
    var APIBaseUrl: String = "http://api.themoviedb.org/3/movie/upcoming?api_key="
    var urlString:String = "\(APIBaseUrl)" + "\(APIkey)"

    //Call the API by using the delegate and passing the API url
    self.api.delegate = self
    api.GetAPIResultsAsync(urlString)

Make sure to replace the empty API key with your own.

That’s it, run the application.

If you have followed the steps successfully your application should run and display all upcoming movies.

Final App

I hope you have enjoyed writing this app using Swift as much as I have and I can’t wait to see the next great apps that will be created using it.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • ElDerecho

    I am really hope they port it, or allow it to be ported, to other platforms. The language looks like it strikes a great balance between easy-to-learn scripting languages and native code compiled languages. And I am far from an Apple fan. But they did a good job on Swift.

    • KathrynDBradsher

      Start working at home>>CLICK NEXT TAB FOR MORE INFO AND HELP

  • vali nagacevschi

    Hi,

    Nice tutorial! Great job. I followed to letter and it compiles ok.
    But when running, I get exc_bad_instruction exc_i386_invop on line:

    let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as UITableViewCell

    Don’t know how to move forward. Is there any param to change?
    Thanks,

    • Chris Ward

      Hey guys, I also got the code to compile and run, but being a beta Xcode does crash occasionally etc etc…

  • Guilherme Akio Sakae

    There’s any change you fix the github repo? it’s blank now.

    I’ve found some errors when I try to compile the app, like the ViewController does not perform to UITableViewDataSource. When I change the UIViewController to UITableViewController I can compile, but when I try to add the protocol I get the same error but now with the new protocol.

    Maybe they have changed somethings in the xcode beta3 (version that I’m using)

  • vali nagacevschi

    Hi Patric,

    Thanks for the reply. That was also my first guess and I checked from the browser the link with my api key.
    I got a json with the list of movies which I suspect is correct.
    I’ll look at the repo to see what I missed.
    Thanks,

  • Chris Ward

    A very timely blog post from Apple – https://developer.apple.com/swift/blog/

  • Patrick Haralabidis

    Xcode 6 beta is now available to all registered Apple developers. You do not need to be a member of the iOS or Mac developer program in order to download and use it.

    https://developer.apple.com/news/?id=07112014a

  • Jaycee

    hi, I compiled the first set of code where it need to generatea just a blanck table..It says
    unable to run in simulator..An error was encountered while running (Domain = FBSSystemServiceDomain, Code = 4)

    • Patrick Haralabidis

      Hi,
      It’s an issue with the beta version, try to quit and restart the simulator and Xcode.

      That worked for me.

  • http://www.mahurangi.school.nz Vern Dempster

    Hi. Thanks for the great introduction. However I cannot get past 1st base on the tutorial as I have followed your instructions. I dragged a table view object but do not get the menu on the left like yours and am unable to click and drag from tableview to the view controller. I can get a popup menu but unable to drag from there to anywhere other than itself. Sorry I am not explaining this well. Any help would be greatly accepted.

    • Patrick Haralabidis

      Hi Vern,

      If this is the first time you started Xcode it may not look like mine in the screenshots as some windows are closed.
      If I understand your problem correctly, you want to link the table view to the controller but cannot see the document outline to the left.

      To see the document outline, click on “editor” on the Xcode menu bar at the top, then select “Show Document Outline”.
      Alternatively, you can hold control, and then click and drag from the tableview to the yellow controller icon directly above.

      • http://www.mahurangi.school.nz Vern Dempster

        Thanks, “Show Document Outline” solved it as well as me realising I should drag a table view and not a table view controller into the default view controller( which it won’t do haha). Also in safari line 19 of the APIcontroller shows as
        if jsonResult.count>0 && jsonResult["results"].count > 0 {

        and I had to get rid of the 2x amp;. and it all worked. Many thanks

  • Fernando Serapio

    I followed the tutotial step by step and xcode throws me a error “fatal error: unexpectedly found nil while unwrapping an Optional value” in this line:

    let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as UITableViewCell

    this is my first time on xcode and ios development, i have seen in the status of the API in my profile that that the app is actually calling to it

    • Patrick Haralabidis

      Hi Fernando,

      I’m not sure if this is cause by a different or newer version of Xcode.

      This issue normally occurs when you have no data to populate the cells.
      Have you verified that there is data being returned from the API call?

      To verify, put a breakpoint in this line in the APIController
      if jsonResult.count>0 && jsonResult["results"].count > 0 {

      and check the data that is returned in the JsonResult.

      If you have null or empty values, add a check with an if statement in the tableView function following the great example that J Soho posted here.

  • David N. Brett

    Hi, and thanks for this tutorial !
    Had to modify the tableview functions to get it working.

    Replaced :
    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
    By :
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int

    And :
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
    by :
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell

  • Rudy Folden

    Just what I was looking for. Unfortunately, the code does not compile with XCode version 6.1 (the latest).