IOS8 app development on Apple Swift

Original author: Jameson Quave
  • Transfer
  • Tutorial
The article is a kind of continuation of the article “ Meet Swift! " By Helecta , as well as a free translation of the article Developing iOS Apps Using Swift Tutorial Part 2 .



So, in the first article, we wrote a simple Single View application that includes a table with several cells.
This time we will go a little deeper and do some more ambitious things. We will go to the iTunes search API, parse the response received in JSON and display the results in the Table View.
At first glance, it may seem that all this is rather complicated and there is a lot of work to be done, but in fact it is not. Everything described above is quite simple functionality for iOS applications and every self-respecting iOS developer should be able to.

We will need a Single View Application with the added Table View. We will not dwell on this, since all this is quite simply described in the first article.

Interface Connection


To get started, we need to get a pointer to our Table View in order to use it in the application code. We go to the ViewController.swift file and immediately in the class initialization (class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {) add the following line:
@IBOutlet var appsTableView : UITableView

This will allow us to associate the Table View in the Storyboard with the variable “appsTableView”.
We pass to the Storyboard. We click on the View Controller with the control held down and drag the cursor to the Table View, thereby linking these objects. In the Outlets menu that appears, select “appsTableView”.


Request API Execution


Now, after we have connected the interface, we can execute our API requests.
In the ViewController.swift file inside the initialization of the ViewController class, create the searchItunesFor (searchTerm: String) function.
func searchItunesFor(searchTerm: String) {
    // Для The iTunes API слова в поисковом запросе должны быть разделены при помощи "+", поэтому нам необходимо произвести соответствующие замены.
    var itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
    // Помимо этого, необходимо удалить все что не URL-friendly
    var escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
    var urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=software"
    var url: NSURL = NSURL(string: urlPath)
    var session = NSURLSession.sharedSession()
    var task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
        println("Task completed")
        if(error) {
            println(error.localizedDescription)
        }
        var err: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
        if(err?) {
            println(error.localizedDescription)
        }
        var results: NSArray = jsonResult["results"] as NSArray
        dispatch_async(dispatch_get_main_queue(), {
            self.tableData = results
            self.appsTableView.reloadData()
            })
        })
    task.resume()
}


Let's go in order.
We correct our search query so that the iTunes API receives a text of the form "First + Second + Third + Words" instead of "First% 20Second% 20 ...". To do this, we use the stringByReplacingOccurencesOfString method available in NSString, which replaces spaces with "+".
Next, we clear the resulting string from characters that are not supported by the URL.
The next two lines define the NSURL object that will be used as a request to the API.
Let's pay attention to the following two lines:
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in

The first takes the standard NSURLSession object, which is used for network calls.
The second creates a task that sends a request.
Finally, the line task.resume () begins the execution of the request.

Preparing to receive a response


We got a method that, when called, performs a search in iTunes. Insert it at the end of the viewDidLoad method in our ViewController.
override func viewDidLoad() {
    super.viewDidLoad()
    searchItunesFor("Angry Birds")
}

Now, in order to get an answer, you need to add an object that will store the search results.
Therefore, we will add the NSMutableData instance and the NSArray array to store data for our table (inside the initialization of the ViewController class, for example, immediately after the pointer @IBOutlet var appsTableView: UITableView).
var data: NSMutableData = NSMutableData()
var tableData: NSArray = NSArray()

Now, let's combine the functions that NSURLConnection will send to our class. Since this is the delegate of our request, any information from NSURLConnection will be returned by the protocol methods defined in NSURLConnectionDataDelegate and NSURLConnectionDelegate. Therefore, in the initialization of the ViewController, we also specify NSURLConnectionDelegate, NSURLConnectionDataDelegate, there will be something like:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate {


Receive response


We have to add the largest part of our application code to process the received information.
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
    self.data = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
    self.data.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
    var err: NSError
    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options:    NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
    if jsonResult.count>0 && jsonResult["results"].count>0 {
        var results: NSArray = jsonResult["results"] as NSArray
        self.tableData = results
        self.appsTableView.reloadData()
   }
}

When the NSURLConnection receives a response, the didReceiveResponse method is called.
Here we simply dump our data, if there was any, by writing self.data = NSMutableData () to create a new object.
After the connection is established, we begin to receive data in the didReceiveData method. Here the argument is passed data: NSData, where all the information we are interested in is located. We need to save all the parts received in the response, so we attach them to the self.data object created above.
Finally, after we have received all the information in the response, the connectionDidFinishLoading method is called, where we can already start using the result.
We will use the NSJSONSerialization class to convert raw data into useful information in the form of NSDictionary dictionary objects.
Now that we have verified that we received some kind of response from iTunes, a simple check of the “results” key will be enough to make sure that we got exactly what we expected, so we can set the self.tableData object to results, and also refer to the method tables appsTableView.reloadData () to update its contents.

Table View UI Update


To initialize the Table View in the first article, we needed to define two functions: one returns the number of rows in the table, the second created the cells and described their contents.
We will update these functions in accordance with the new functionality.
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")
    var rowData: NSDictionary = self.tableData[indexPath.row] as NSDictionary
    cell.text = rowData["trackName"] as String
    // Обращаемся к ключу artworkUrl60 для получения ссылки на обложку объекта
    var urlString: NSString = rowData["artworkUrl60"] as NSString
    var imgURL: NSURL = NSURL(string: urlString)
    // Скачиваем файл обложки в объект NSData для последующего отображения в ячейке
    var imgData: NSData = NSData(contentsOfURL: imgURL)
    cell.image = UIImage(data: imgData)
    // Получаем цену объекта по ключу formattedPrice и отображаем ее в качестве subtitle
    var formattedPrice: NSString = rowData["formattedPrice"] as NSString
    cell.detailTextLabel.text = formattedPrice
    return cell
}

The numberOfRowsInSection function now simply returns the number of objects received in the response.
The cellForRowAtIndexPath function instead of displaying the line number now displays the name of the object, its cover and value.

If everything is fine and you manage to run the application, you may notice some “lags” during its operation. This is due to the fact that we did not provide for several things that we will pay attention to in the next article.

PS: After the release of my translation, the author updated the lesson somewhat, optimizing the code a bit. I tried to bring the translation in line.

Only registered users can participate in the survey. Please come in.

Should the following articles be translated from this cycle?

  • 90.2% Yes 660
  • 9.7% No 71

Also popular now: