Developing iOS Apps Using Swift Tutorial Part 2


This section completely updated to reflect changes in Xcode 6.3, as of April 16, 2015

In part 1 we went over some basics of Swift, and set up a simple example project that creates a Table View and a puts some text inside of them. If you haven’t read that yet, give it a read here.

For this section, we’re going to do something a little more ambitious. We’re going to hit the iTunes Search API for the iTunes Store, download the JSON results, parse them in to Dictionaries and then populate our Table View with this information. Then, we will add some user interaction by adding a click event to the tableview, so that when an item is clicked the iTunes store item will be opened.

If this sounds like a lot of work, don’t sweat it. This is pretty basic functionality for iOS apps and it’s one of the most common things any developer has to do. Let’s get going…

Connecting the UI

The first thing we need to do is get a reference to our tableView, so it can be used from code. Go ahead and add this line to your ViewController.swift file, just under the class definition, but outside of any functions.

@IBOutlet var appsTableView : UITableView!

This bit of code allows up to connect our Table View in our Storyboard to this variable, “appsTableView”. Save this file and open up your storyboard. Now select the View Controller object (the one with a yellow icon) and in the right-hand side pane click the last tab, the Connections Inspector. Here you should now see an outlet for “appsTableView”. Click and drag from the dot next to this outlet on to the Table View in our scene.

Let’s also add a variable to hold the table data itself. Just under the class definition for ViewController add:

var tableData = []

Making the API Request

Now that we have the UI connected, we’re ready to make an API call. Create a new function called searchItunesFor(searchTerm: String). We’ll use this to make our requests happen for arbitrary search terms.

To keep this tutorial short, I’m going to just post my final code and let the comments do some of the explaining. I’m always open to questions and further discussion in the comments though, so feel free to chime in!

func searchItunesFor(searchTerm: String) {
    // The iTunes API wants multiple terms separated by + symbols, so replace spaces with + signs
    let itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
    // Now escape anything else that isn't URL-friendly
    if let escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
        let urlPath = "\(escapedSearchTerm)&media=software"
        let url = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
            println("Task completed")
            if(error != nil) {
                // If there is an error in the web request, print it to the console
            var err: NSError?
            if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary {
                if(err != nil) {
                    // If there is an error parsing JSON, print it to the console
                    println("JSON Error \(err!.localizedDescription)")
                if let results: NSArray = jsonResult["results"] as? NSArray {
                    dispatch_async(dispatch_get_main_queue(), {
                        self.tableData = results
        // The task is just an object with all these properties set
        // In order to actually make the web request, we need to "resume"

Let’s go line-by-line.

First, we need to do some fixing of the search terms we pass in, the Search API wants terms in the form of “First+Second+Third+Words” rather than “First%20Second%20…” etc. So instead of URL-encoding, we use an NSString method called stringByReplacingOccurencesOfString. This returns a modified versions of the searchTerm variable with all our spaces replaced with + symbols.

Next, we actually escape the search term in case there are other symbols that won’t fit in a URL by using the function stringByAddingPercentEscapesUsingEncoding.

The next 2 lines define an NSURL object that can be used as a Request URL for iOS’s networking API.

These next two lines are what gets us going with a NSURLSession and defines the task we want it to perform. This is were the heavy lifting begins, as the dataTaskWithURL method takes a closure as it’s final argument, which is executed after a request is sent, and a result is determined.

let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in

The first line grabs the default NSURLSession object. This is used for all our networking calls. The second line then creates the connection task which is going to be used to actually send the request. dataTaskWithURL has a closure as it’s last parameter, which gets run upon completion of the request. Here we check for errors in the response, then parse the JSON, and call the delegate method didReceiveAPIResults.

Finally, task.resume() actually begins the request.

Because this task happens in the background, we need to jump in to the foreground before we update the UI. So we need to use dispatch_async to move back in to the main thread, and reload the table view. The first argument specifies the thread the update should perform on, which we specify as dispatch_get_main_queue(). This is a built-in method that simply returns the main thread (the UI thread).

Making the API call

Now we’ve got a method that starts an iTunes search response when we call it. So let’s insert the following at the end of viewDidLoad…

searchItunesFor("JQ Software")

This will find any software products on the iTunes store containing that phrase, which in this case will include a couple of games and various apps.

Receiving the response

Finally our request code is done and all data has been received, didReceiveAPIResults is called and we’re ready to use the data in our app. Hooray!

The closure method here uses the NSJSONSerialization class to convert our raw data in to useful Dictionary objects by deserializing the results from iTunes.

We can now set our self.tableData object to be the resulting data, and tell the appsTableView to reload it’s content. This will cause the Table View object to run it’s own delegate methods. Defining this is the final step in this part of the tutorial.

Updating the Table View UI

You may remember from last time we implemented the function for our Table View that we had a count method, which determines the number of rows; and a cell method, which actually creates the cell and modifies it for each row.

We’re going to update these now to use the data we pulled down from the web.

Swap out your methods with these two functions:

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
    if let rowData: NSDictionary = self.tableData[indexPath.row] as? NSDictionary,
        // Grab the artworkUrl60 key to get an image URL for the app's thumbnail
        urlString = rowData["artworkUrl60"] as? String,
        // Create an NSURL instance from the String URL we get from the API
        imgURL = NSURL(string: urlString),
        // Get the formatted price string for display in the subtitle
        formattedPrice = rowData["formattedPrice"] as? String,
        // Download an NSData representation of the image at the URL
        imgData = NSData(contentsOfURL: imgURL),
        // Get the track name
        trackName = rowData["trackName"] as? String {
            // Get the formatted price string for display in the subtitle
            cell.detailTextLabel?.text = formattedPrice
            // Update the imageView cell to use the downloaded image data
            cell.imageView?.image = UIImage(data: imgData)
            // Update the textLabel text to use the trackName from the API
            cell.textLabel?.text = trackName
    return cell

The numberOfRowsInSection is now simply returning the number of resultant objects from the tableData member, which is set in our prior connectionDidFinishLoading method.

The cellForRowAtIndexPath is also not changed dramatically in this case. Rather than simply returning the row number, we use the row number to grab three pieces of information: the track name, the artwork url, and the price.

Using these keys we construct the title, subtitle, and an image to go along with the cell.

If you’re coming from another language, you may notice the syntax is a little unusual here. The syntax goes something like this:

if let variableA = optionalThing as? Type,
    variableB = anotherOptionalThing as? Type {
        // variableA and variableB are confirmed to exist

This is part of optional binding. The statement “if let variableA = optionalThing as? Type {}” will only execute the code within {} if optionalThing is able to be casted to Type. It’s a check.. can we assign a variable called variableA to optionalThing as a type of Type? If so, then execute this next bit of code. You can also specify multiple checks, in this case we check if both variableA and variableB are able to be assigned, if so then we execute the code in the block.

We use optional binding in our cellForRowAtIndexPath method in order to make sure artworkUrl60, formattedPrice, and trackName are actually keys we get back from the API. If any of these fail, the code within the curly braces is skipped, preventing an error from occurring when we try to set the text or image to a nil value.


Try running our app, and you’ll see we for the first time have created something that actually looks like an app all in Swift!

But, why is it so laggy!?
If you scroll around you might notice it lags when showing table view cells.
In this tableview, we’re not properly handling quite a few things. Over the next 3 sections we’ll dive in to what that means and what the proper changes we need to make are. If you like, jump ahead to part 5 where these issues are resolved.

In my upcoming book, I delve more deeply in to why this happens. Learn more about it here.

Next time in Part 3 we’ll work on the interaction piece of the app, allowing users to search for anything they like, and making the table cells clickable!

The completed source code to this section is available here.

Go to Part 3 Now ->

Follow me on Twitter

Sign up now and get a set of FREE video tutorials on writing iOS apps coming soon.

Subscribe via RSS

125 thoughts on “Developing iOS Apps Using Swift Tutorial Part 2

  1. Great to see a tutorial up so quickly, after nearly 3 years I consider my self to be a good iOS programmer, as I have not had much exposure to other languages one thing confuses me a bit in terms of structure in Swift.

    In OjbC you have a header where anything public i.e. available to external classes, and then properties could either be in the .m or .h depending on if they were private or public.

    I have played a bit with Swift, Am i right in understanding that all properties are now available to other classes unless declared inside a function. Also how do functions become private?

    Regards Melvin

    • Melvin, thank you for your comments. The header files are the old tried and true way of determine what classes can see what, but in Swift we’re dealing with something quite different. It does in fact appear that the only way to make something private is to put it inside a function. This is not unlike javascript, and has become a common pattern to make ‘modules’ out of functions in order to create encapsulated systems.

      Regarding actually making a function private, the easiest way is to use the module pattern. I’ve created a Gist for you here. Everything you see in this file is public, except the function named ‘someInnerFuncVar’.

      • I find this pattern somewhat confusing coming from a more purely object-oriented background. Your example shows how a single function might use a nested function to hide it, but how does a class maintain private state that needs to be accessible from multiple functions? Or let’s say that your nested function would be useful somewhere else in the class – how do you implement utility functions in a class (in a DRY way) that should never be called from outside the class?

        In Obj-C, the de facto way to do this would be to add properties to the anonymous class continuation category in the .m file, effectively “hiding” them from the outside world, or to implement methods only in the source file and not declare them in the public header. There was also the option of creating a “protected” header for use by subclasses but not as a public interface.

        Is there any possible way to do things like this in swift? If not, it seems like clean API design will be very difficult, and that open-source libraries will be full of “// DO NOT USE THESE FUNCTIONS”

        I’m wondering why they didn’t just adopt the public/protected/private access model of c++ and similar languages. You still wouldn’t need a header, but it would be much easier to restrict access to properties and functions that nothing else has any business futzing with.

        • I read somewhere that private, protected, public etc. are coming to Swift in a near future. Apparently it was something that wasn’t ready. I believe I read this on some Apple forum where an Apple engineer replied.

  2. Thanks Jameson, thats what I kind of figured, it does represent a new approach it seems. Looking forward to the rest of the series.

  3. Hey. Thanks for these tutorials, I’m an Android developer with pretty much no experience with iOS, and your first couple of tutorials have been straight forward and make sense to an outsider like myself.

    • That’s great to hear! There are for sure some best practices that will need to be added in. I was planning to follow up with more interaction, but I may take a pit stop and start refactoring what we already have with proper code architecture principles. This code is not yet ready for production 🙂

      • No worries. I write a blog on Android development, and the code is always a proof of concept moreso than “I promise this won’t make your fellow developers want to strangle you”

  4. Hi! Great tutorial!
    I was playing with the code and run into some trouble.
    if I change



    cell.text = rowData[“trackName”] as String
    But if I println(rowData[“trackName”]) it prints fine on the console.
    Any thoughts?
    Thank you very much!

    • Try a println() on the JSON response before you try to access its members. Its possible the music results don’t always include a trackName. Normally I would add error checking to validate the key before using it, but like all of us I’m still fresh and it’ll probably come in part 3 🙂

      • When searching for software I’m getting a valid JSON response but am unfortunately also getting the same error as Guillermo. Any ideas?

          • I’m getting this same issue too. I tried the above fix but didn’t help.

            My Xcode throws a breakpoint in at the `if jsonResult` line and when continuing to iterate through, the error I get in console is: fatal error: Can’t unwrap Optional.None

            I haven’t changed the code you’ve provided except for the cellText lines above trying to fix this

            Thanks for the tutorial! It’s been helpful, just too green to know how to debug this at this point

          • One additional note on my comment, it happens on the second item when iterating through, I get the above error and EXC_BAD_INSTUCTION as noted above

        • I think there is probably something wrong with the cell. Try setting up a re-use identifier in a prototype cell in your storyboard. This is discussed more in depth in Part 4.

    • I received this error as well. On my end, ctrl+drag+dropping from the ‘Table View’ to the ‘View Controller’ did not connect “var appsTableView : UITableView” as my referencing outlet.

      To Fix: I had to go back to the storyboard, ctrl+click on the “Table View” and then under “Referencing Outlets” select “appsTableView”;

      Hope this helps. Not sure why it didn’t connect in the first place.

      • I’m experiencing the same error Weirdly, I don’t even see ‘appsTableView’ underneath ‘Referencing Outlets’ at all. Even though I have ‘@IBOutlet var appsTableView : UITableView’ in the ‘ViewController’ class.

        • Fixed by dragging the TableView from the Storyboard into the ViewController, whereby it created a new IBOutlet.

          Curiously, the one it created had ‘ = nil’ on the end, not sure how important that is?

          Either way, it’s now linked up and working. Great tutorial! 🙂

          • Not fixed to me. I can’t link it.
            however, I have a lot of Xcode6Beta crashes while editing code. Have anyone the same issues?
            Maybe I need to download again.

    • i was getting the same “fatal error: Can’t unwrap Optional.None”. As mentioned by others looks like this occurs because the outlet is not getting created when the drag/drop from table view to controller occurs. In order to fix mine, I opened up the assistant editor so that the storyboard file and the viewcontroller.swift file were visible side by side and I did the drag/drop from the tableview straight into the code file. All compiled and ran perfectly after that. Great tutorial so far, really learning a lot considering I have extremely limited Obj-C experience (coming from a .Net background). Looking forward to working thru the rest of the blog posts.

  5. Just wanted to say well done on what is an easy to follow tutorial. Always good to have someone dive right in there and show how old things can be done anew! I’ll be singing your praises from the rooftop and see what I can do to create some exposure for your swift tutorials.

    I’m looking forward to the next one.

  6. Thanks for the quick tutorial. Will follow this for next episodes for sure.

    I’m familar with Obj-C but Swift is way faster to code things.
    atm I am totaly into Swift and trying to learn the ups and downs.
    The only draw back is, it does not support OS X 10.8 or lower.

  7. I followed along but where I ran into trouble was I made a data class and then in my View Controller I made a couple instances of that data class and tried storing those instances in an array so I could then fill my views rows by looping through the array.

    I get an error when I try storing the instances in an array have you tried this yet or know if its possible in swift? Seems like when I create my instances then try to store them in the array it doesn’t know they exist yet.

    Thanks for the great tutorial!

  8. Just for this quick and easy intro to Swift.
    However I’m having performance issues. When querying for “Disney” I’m getting a tableview of about 30 rows or so. But when scrolling the performance is just terrible. Slow. Could it be because of the images?
    Btw it happens both on my mac using simulator (iOS8) and on my iPhone 5 running iOS7

    • Yep you would want to ideally have caching of images and asynch loading. This demo intentionally cut all that out to keep things very simple. I’m working on the async right now for Part 5.

  9. I think we can replace this part

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

    with another one that using threads or downloading images in the background. I think the previous code will wait till all images loaded first.

  10. I had a strange problem. I’m doing everything programmatically(i think that this way i can learn more) and my cellForRowAtIndexPath is not being called! ‘oO’
    Even setting my delegates and datasource protocols and related methods, this method not get called… The strange thing is that my numberOfRowsInSection is called(first when we load the view and add the tableView as a subview, and than later, when i reload my tableview’s data once my request is finished). It is very strange… Here is a gist of my mainController that is being called as a rootVC in the window setted in my AppDelegate.swift :

    I used to make Lazy load in my setters(in fact, i made this in my swift code too), but i’m a bit confused, because now we have a keyWord called @lazy for this things.


    • Tiago, this means probably one of two things:
      1) Your tabledata has 0 rows for some reason
      2) Your method signature does not match the expected method signature for the table view delegate/datasource

      But it’s probably #1

      • I thought that it was one of these erros.
        After the request is finished, my array has 4 items. But when i call reload data, it does not call cellForRowAtIndexPath…
        I had keep track of the states in this variables in each time. In relation to my method signature, it is correct, as i change that and the compiler shows me the error that my delegate is not implemented…

        Thanks for the quick answer!

      • I have the same problem. I can see that results are coming back, but tableView(tableView: cellForRowAtIndexPath:) isn’t being called at all. I’ve done a copy/paste from your gist and all I’m getting is a blank table view.

        • The only reason that wouldn’t call is the delegate & dataSource of the tableview isnt set to self. In the storyboard file, click on the table view and go to the very last tab of the panes on the right-hand-side. It’ll show if delegate & dataSource are set.

  11. > Now by control+click+dragging from the Table View to our ‘View Controller’ object, we’ve linked these objects. Easy, right?

    You meant the opposite right? Something like “control+click+drag from our View Controller to our Table View” – that pops up a dialog to select the appTableView property

      • Only worked for me dragging from ViewController object to TableView.

        As a newbie to iOS programming, the fact that you can name multiple functions the same was odd to me. Maybe a quick explanation?

        • You can’t name multiple Obj-C functions the same, but the “name” is defined by the method signature. In objective-c if you have a method like this:
          – (void) myMethodName:(int)myFirstParameter withASecondParameter:(int)mySecondParameter;
          Then the method name in Swift is “myMethodName(…)”, so for this reason you may see what seems to be methods with the same names doing different things, but that’s because under the hood, the named parameters in Swift are part of the method signature in Obj-C:
          “myMethodName: withASecondParameter:”

  12. Hi,

    first I want to thank you for this tutorials!!! Now the question. Why in connectionDidFinishLoading you use data instead of

    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

    Im a newbie in IOS 🙂

  13. Hi,

    I’m doing your tutorial and it is working. Now I’m trying to adapt it to my project.
    Is there a simple way to parse a Json using swift ?
    I have a json like:
    “title”: “Train speed”,
    “description”: “speed”,
    “images”: [
    “position”: 1,
    “item”: [
    “url”: “myurl_1”,
    “width”: 640,
    “height”: 359
    “size”: “L”,
    “url”: “myurl_2”,
    “width”: 320,
    “height”: 179
    “size”: “M”,
    “url”: “myurl_3”,
    “width”: 160,
    “height”: 89
    “size”: “M”,
    “url”: “myurl_4”,
    “width”: 160,
    “height”: 89

    For the moment I managed to parse it using loop inside loop and loop again.
    Here is what I did:
    if let element = rowData[“images”]{
    var rowDataImg: NSDictionary = element[0] as NSDictionary
    if let element1 = rowDataImg[“item”]{
    var rowImgUrl: NSDictionary = element1[0] as NSDictionary
    var urlString: NSString = rowImgUrl[“url”] as String
    var imgURL: NSURL = NSURL(string: urlString)
    var imgData: NSData = NSData(contentsOfURL: imgURL)
    cell.image = UIImage(data: imgData)



    • var deserializedJSON: NSDictionary = NSJSONSerialization.JSONObjectWithData([myJsonString.dataUsingEncoding(NSUTF8StringEncoding)], options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

  14. Thanks for the answer.
    I’m a beginner in iOs App (I’m a java developper actually) .
    Can you please show me how to get the value (for instance) of the “url” attribute? Can I use something like a xpath ?
    I’m used to groovy where you just do something like deserializedJSON.att1.att2.att3 ..


    • Try this:
      var images: NSArray = deserializedJSON[“images”] as NSArray
      var items: NSArray = images[“item”] as NSArray
      var firstItem: NSDictionary = items[0] as NSDictionary
      var url: String = firstItem[“url”] as String

      The main issue here is that the JSON is being deserialized in to Obj-C types, NSDictionary and NSArray. If it were a pure Swift object it would be much better, but that API doesn’t seem to exist yet. Maybe I’ll write it.

      • I tried but it does not work.
        It fails at:

        var items: NSArray = images[“items”] as NSArray

        with the message: Cannot convert the expression’s type NSArray to type StringLiteralConvertible.

        Any idea?
        I’ve tried some stuff but I cannot get the thing working.


        • I am having a very similar problem, getting these two errors:

          var rowData: NSDictionary = self.tableData[indexPath.row] as NSDictionary <-'NSArray' is not convertible to 'NSDictionary'


          self.tableData = results <- 'AnyObject' is not identical to 'NSArray'

          Any ideas as to why?

  15. Hi Jameson,

    I have tried with tutorial which you have sent, but one problem i’m facing is “fatal error: Can’t unwrap Optional.None”, this error is raising on the self.appsTableView.reloadData()……

    Please help me regarding this to move forward

  16. This is a great tutorial and I am really enjoying it however, I noticed that you’re not using the baked in inference that helps make this language so light. Any particular reason?

    • I start using it more later in the series. The only reason I’m doing it in the beginning is because I’m used to it. I would go back and remove it, but I also think it helps explain what’s happening under the hood a bit.

  17. Is part 2 in github by chance? I’m getting an error in connectionDidFinishLoading but am also noticing that connection(didRecieveResponse) and connection(didRecieveData) are not being triggered. URL seems good so my delegate connection must be broken somewhere.


  18. Minor nit, but it may also have an unexpected consequence.

    You are systematically misspelling “receive” as “recieve,” except in the one case where it really matters. Normally, I wouldn’t care, but you have a callback function:

    func connection(connection: NSURLConnection,
    didRecieveResponse response: NSURLResponse) {
    println(“Recieved response”)

    Is this function just never going to be called, because it is misnamed? What will happen if the system really does want to call this method and it finds this misnamed method? Is it just ignored?

  19. Hey great tutorial!

    There’s one line in your searchItunesFor function that puzzles me:
    var results: NSArray = jsonResult[“results”] as NSArray

    I’m wondering: where did you get the argument name [“results”] ? Meaning how did you know to use that name and not some other name? And are there other names or values that can be used there?


    • actually, I can answer my own question here 🙂

      “results” comes directly from the iTunes Search API itself: that’s the word they use for returned JSON results. So it comes from Apple. All I had to do was look that up…

      thanks anyway – keep up the good work!

  20. I’m trying to use this code as a base for accessing another JSON API, but whenever I change the URL and try to run it I get an EXC_BAD_INSTRUCTION error on the line ” println(error.localizedDescription)” If I try to comment out that line, I get errors pretty much all the way up. Would this code only work for this particular API or am I just doing something wrong?

    • It should work the same with any API, I’m going to say there’s probably a different issue. I’m guessing you need to modify the way it’s deserialized a bit due to a difference in the way the data is structured.

  21. Great Tutorial!! I do have one question though. How would I go about connecting to a url that required username/password authentication? Thanks!

  22. Doesn’t compile on xCode 6 Beta 3.

    cell.text -> cell.textLabel.text

    Not sure what to do with cell.image though – I find it difficult to see what to do with deprecations, in java we usually get a comment with a clue as to what has replaced the deprecation

    • Just left a comment, but change:

      cell.image = UIImage(data: imgData)
      cell.imageView.image = UIImage(data: imgData)

  23. In the latest Xcode6-Beta3, you won’t be able to run your program (due to deprecation errors) until you change the following:

    cell.image = UIImage(data: imgData)

    cell.imageView.image = UIImage(data: imgData)


    cell.text = rowData[“trackName”] as String

    cell.textLabel.text = rowData[“trackName”] as String

  24. Hey, I’m new to Swift and trying to follow your tutorial. I’m using xcode 6 – beta 5 and im getting a compile error for the line after jsonResult

    if (err?)

    Type NSError? does not conform to protocol ‘BooleanType.Protocol

    and in the console

    fatal error: unexpectedly found nil while unwrapping an Optional value

    This is likely an error on my part, just wondering if anybody else could reproduce it. Thanks for the tutorial

  25. My build is apparently successful but my table is blank. I checked that my view controller is connected to my delegate and datasource. Any idea what Could be going on here? Would have anything to do with me using Xcode Beta 2?

  26. I’m getting this error: The operation couldn’t be completed. (NSURLErrorDomain error -1002.)
    It’s getting thrown here:
    if((error) != nil) {
    // If there is an error in the web request, print it to the console

    I’m using Xcode 6 beta 6

  27. Thanks for making these guides!

    I ran into some troubles running the code :

    “Task completed
    The operation couldn’t be completed. (NSURLErrorDomain error -1002.)
    fatal error: unexpectedly found nil while unwrapping an Optional value”

    failing on line :
    var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary

    Im using beta6

  28. Just upgraded to Xcode 6 beta 6. When I run this tutorial (part 2) as described above, I get “The operation couldn’t be completed. (NSURLErrorDomain error -1002.)
    fatal error: unexpectedly found nil while unwrapping an Optional value”

    If I modify the URLPath and put something in like:
    let urlPath = “”

    Then it works fine. Is it possible that beta 6 might have changed something and now your original code is returning an empty set from iTunes?

    All the xcode beta (breaking) changes almost make noobs like myself want to wait until it’s finally released…almost… 🙂

  29. I see above that you fixed the code for Beta6, but I am running beta 6 (6A280e) and I keep getting…

    The operation couldn’t be completed. (NSURLErrorDomain error -1005.)
    fatal error: unexpectedly found nil while unwrapping an Optional value


    var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary

    I even checked out your github repo to verify it wasn’t my coding mistake.

  30. It’s rather counterproductive to create a comprehensive tutorial for a new programming language if three months in you stop updating the code. Please keep your material up to date and accurate or remove it so people can learn accurate information.

  31. i have questions:
    1)why swift is a compilery language when it runs the same time?
    2)when we can exchange the data o fvariables this is correct?
    var name = “hello”
    name = 20 //exchange string to int

  32. Jameson Quave you can write the txt of the Conference that intruduction of swift?
    whit link:http:

  33. Hey, thanks for the tutorial. however i needed to add a question mark at the end of these two in order for it to work:

    cell.textLabel?.text = rowData[“trackName”] as? String
    cell.imageView?.image = UIImage(data: imgData!)

    • Whether or not these properties are optional (and therefore whether or not they need the question mark) has been changing with every version of Xcode, so it’s slightly different for everyone. However, Xcode will automatically suggest fixes to these issues.

      In either event, you should learn why this is happening by reading up on Optionals in Swift and how they work.

  34. Hi,

    thanks for your great work here. I’m new to Swift (and iOS programming).

    I’m trying to run the code example above and I’m constantly getting the same mistake (even if I download your code from GitHub) – I’m using Xcode 6.1.1

    In ViewController.swift

    cell.textLabel.text = rowData[“trackName”] as? String
    Error: UILabel? does not have a member named ‘text’
    cell.imageView.image = UIImage(data: imgData!)
    Error: UIImageView? does not have a member named ‘image’

    Any idea how I could solve this?


    • could solve it by myself:


      cell.textLabel.text = rowData[“trackName”] as? String
      cell.textLabel!.text = rowData[“trackName”] as? String


      cell.imageView.image = UIImage(data: imgData!)
      cell.imageView!.image = UIImage(data: imgData!)

      • I’m also new to all of this and I just changed it to:

        cell.textLabel?.text = rowData[“trackName”] as? String
        cell.imageView?.image = UIImage(data: imgData!)

        I’m not sure what the difference between a “?” and “!” is, but they both seem to get the job done.

        • Using ? is safer, if the textLabel or imageView don’t exist, the code is not run.
          However, if you use !, you are *insisting* that they exist, and if they don’t, the app will crash.

  35. Hi,

    Great tutorial man, just fix the “or” to “for” under the line:
    let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in

    and keep going with your great work

  36. I am getting this error:

    “extra argument ‘error’ in call” at this line:

    if let jsonResult = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary {

    the problem seems to be “error: &err”

    I am using Xcode 7beta

    • Xcode 7 Beta uses a new Error handling paradigm. Here’s the short version of how to fix cases like this:

      1) Delete the error argument, and any references to the err variable.
      2) Put try! in front of the call that used to have the error argument (this is unsafe, but will help you get through this for now)

    • Oh you don’t need to set them to nil, we aren’t really interested in the differences in the option for this tutorial. The options basically just control whether or not you can modify values after retrieving them

  37. Doing this way build is ok

    if let jsonResult = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableLeaves) as? NSDictionary {
    if let results: NSArray = jsonResult[“results”] as? NSArray {
    dispatch_async(dispatch_get_main_queue(), {
    self.tableData = results

    but I get an error when launching the app

    2015-06-14 13:04:28.066 iTunesSearch[1578:295858] CFNetwork SSLHandshake failed (-9824)
    2015-06-14 13:04:28.068 iTunesSearch[1578:295858] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
    Task completed
    An SSL error has occurred and a secure connection to the server cannot be made.
    fatal error: unexpectedly found nil while unwrapping an Optional value

  38. Hi, thanks for the tutorial, it’s very interesting so far. I just ran into something that may be due to newer changes, perhaps? I’m not sure. Copying and pasting in the code above for tableView results in XCode giving some errors and it won’t compile:

    For the lines:
    if let rowData: NSDictionary = self.tableData[indexPath.row] as? NSDictionary,
    // Grab the artworkUrl60 key to get an image URL for the app’s thumbnail
    It’s complaining: “Expected ‘{‘ after ‘if’ condition”.

    And then a few lines further down for:
    trackName = rowData[“trackName”] as? String {
    It’s complaining: “Braced block of statements is an unused closure”.

    Being new to Swift I’m not sure yet how to address these but I’ll dig into it. Any suggestions would be great. Thanks for putting the work into this for us all!

  39. Hi, I think the code dosent work for XCode 7.3, would be nice it you could give some hints in fixing the problems, im new to IOS, would be nice.