Статья является своеобразным продолжением статьи «Знакомьтесь, Swift!» за авторством Helecta, а также вольным переводом статьи Developing iOS Apps Using Swift Tutorial Part 2.
Итак, в первой статье мы написали простое Single View приложение, включающее таблицу с несколькими ячейками.
На этот раз мы немного углубимся и сделаем несколько более амбициозных вещей. Мы будем обращаться к API поиска iTunes, парсить ответ, полученный в JSON и отображать результаты в Table View.
На первый взгляд может показаться, что все это довольно сложно и предстоит много работы, но на самом деле это не так. Все описанное выше является достаточно простым функционалом для iOS приложений и каждый уважающий себя iOS разработчик должен это уметь.
Нам понадобится Single View Application c добавленным Table View. Останавливаться на этом не будем, так как все это достаточно просто описано в первой статье.
Для начала, нам нужно получить указатель на наш Table View для того чтобы использовать его в коде приложения. Отправляемся в файл ViewController.swift и сразу в инициализации класса (class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {) добавляем следующую строчку:
Это позволит нам ассоциировать Table View в Storyboard с переменной «appsTableView».
Переходим к Storyboard. Кликаем по View Controller с зажатым control и тянем курсор к Table View, тем самым связывая эти объекты. В появившейся менюшке Outlets выбираем «appsTableView».
Теперь, после того как мы подключили интерфейс, можно выполнять наши API запросы.
В файле ViewController.swift внутри инициализации класса ViewController создаем функцию searchItunesFor(searchTerm: String).
Давайте по порядку.
Исправляем наш поисковый запрос, чтобы iTunes API получил текст вида «First+Second+Third+Words» вместо «First%20Second%20…». Для этого мы используем доступный в NSString метод stringByReplacingOccurencesOfString, который заменяет пробелы на "+".
Далее, мы очищаем полученную строку от символов, которые не поддерживаются URL.
Следующие две строчки определяют объект NSURL, который будет использоваться в качестве запроса к API.
Обратим внимание на следующие две строчки:
Первая берет стандартный объект NSURLSession, который используется для сетевых вызовов.
Вторая создает задание, которое и посылает запрос.
Наконец, строчка task.resume() начинает выполнение запроса.
Мы получили метод, который при вызове выполняет поиск в iTunes. Вставим его в конце метода viewDidLoad в нашем ViewController.
Теперь, для того чтобы получить ответ, необходимо добавить объект, который будет хранить результаты поиска.
Поэтому, добавим инстанс NSMutableData и массив NSArray, для хранения данных для нашей таблицы (внутри инициализации класса ViewController, например сразу после указателя @IBOutlet var appsTableView: UITableView).
Теперь, давайте объединим функции, которые NSURLConnection будет отправлять в наш класс. Так как это делегат нашего запроса, любая информация от NSURLConnection будет возвращаться методами протокола, определенными в NSURLConnectionDataDelegate и NSURLConnectionDelegate. Поэтому, в инициализации ViewController укажем также NSURLConnectionDelegate, NSURLConnectionDataDelegate, будет что-то вроде:
Нам предстоит добавить самый большую часть кода нашего приложения для обработки полученной информации.
Когда NSURLConnection получает ответ, вызывается метод didReceiveResponse.
Тут мы просто сбрасываем наши данные, если они были, прописывая self.data = NSMutableData() для создания нового объекта.
После установки соединения, мы начинаем получать данные в методе didReceiveData. Здесь передается аргумент data: NSData, где и находится вся интересующая нас информация. Нам нужно сохранить все полученные в ответе части, поэтому мы присоединяем их к объекту self.data, созданному выше.
Наконец, после того как мы в ответе получили всю информацию, вызывается метод connectionDidFinishLoading, где мы уже можем начать использовать результат.
Мы будем использовать класс NSJSONSerialization для преобразования необработанных данных в полезную информацию в виде объектов словаря NSDictionary.
Теперь, когда мы убедились что получен какой-то ответ от iTunes, простой проверки ключа «results» будет достаточно для того чтобы удостовериться что мы получили именно то что ожидали, поэтому мы можем установить объект self.tableData равным results, а также обратиться к методу таблицы appsTableView.reloadData() для обновления ее содержимого.
Для инициализации Table View в первой статье, нам необходимо было определить две функции: одна возвращает количество строк в таблице, вторая создавала ячейки и описывала их содержимое.
Обновим эти функции, в соответствии с новым функционалом.
Функция numberOfRowsInSection теперь просто возвращает количество полученных в ответе объектов.
Функция cellForRowAtIndexPath вместо отображения номера строки теперь отображает название объекта, его обложку и стоимость.
Если все хорошо и у вас получилось запустить приложение, возможно вы заметите некоторые «лаги» во время его работы. Это связано с тем, что мы не предусмотрели несколько вещей, которым уделим внимание в следующей статье.
P.S.: После выхода моего перевода, автор несколько обновил урок, немного оптимизировав код. Перевод я постарался привести в соответствие.
Итак, в первой статье мы написали простое Single View приложение, включающее таблицу с несколькими ячейками.
На этот раз мы немного углубимся и сделаем несколько более амбициозных вещей. Мы будем обращаться к API поиска iTunes, парсить ответ, полученный в JSON и отображать результаты в Table View.
На первый взгляд может показаться, что все это довольно сложно и предстоит много работы, но на самом деле это не так. Все описанное выше является достаточно простым функционалом для iOS приложений и каждый уважающий себя iOS разработчик должен это уметь.
Нам понадобится Single View Application c добавленным Table View. Останавливаться на этом не будем, так как все это достаточно просто описано в первой статье.
Подключение интерфейса
Для начала, нам нужно получить указатель на наш Table View для того чтобы использовать его в коде приложения. Отправляемся в файл ViewController.swift и сразу в инициализации класса (class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {) добавляем следующую строчку:
@IBOutlet var appsTableView : UITableView
Это позволит нам ассоциировать Table View в Storyboard с переменной «appsTableView».
Переходим к Storyboard. Кликаем по View Controller с зажатым control и тянем курсор к Table View, тем самым связывая эти объекты. В появившейся менюшке Outlets выбираем «appsTableView».
Выполнение API запроса
Теперь, после того как мы подключили интерфейс, можно выполнять наши API запросы.
В файле ViewController.swift внутри инициализации класса ViewController создаем функцию searchItunesFor(searchTerm: String).
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()
}
Давайте по порядку.
Исправляем наш поисковый запрос, чтобы iTunes API получил текст вида «First+Second+Third+Words» вместо «First%20Second%20…». Для этого мы используем доступный в NSString метод stringByReplacingOccurencesOfString, который заменяет пробелы на "+".
Далее, мы очищаем полученную строку от символов, которые не поддерживаются URL.
Следующие две строчки определяют объект NSURL, который будет использоваться в качестве запроса к API.
Обратим внимание на следующие две строчки:
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
Первая берет стандартный объект NSURLSession, который используется для сетевых вызовов.
Вторая создает задание, которое и посылает запрос.
Наконец, строчка task.resume() начинает выполнение запроса.
Подготовка к получению ответа
Мы получили метод, который при вызове выполняет поиск в iTunes. Вставим его в конце метода viewDidLoad в нашем ViewController.
override func viewDidLoad() {
super.viewDidLoad()
searchItunesFor("Angry Birds")
}
Теперь, для того чтобы получить ответ, необходимо добавить объект, который будет хранить результаты поиска.
Поэтому, добавим инстанс NSMutableData и массив NSArray, для хранения данных для нашей таблицы (внутри инициализации класса ViewController, например сразу после указателя @IBOutlet var appsTableView: UITableView).
var data: NSMutableData = NSMutableData()
var tableData: NSArray = NSArray()
Теперь, давайте объединим функции, которые NSURLConnection будет отправлять в наш класс. Так как это делегат нашего запроса, любая информация от NSURLConnection будет возвращаться методами протокола, определенными в NSURLConnectionDataDelegate и NSURLConnectionDelegate. Поэтому, в инициализации ViewController укажем также NSURLConnectionDelegate, NSURLConnectionDataDelegate, будет что-то вроде:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate {
Получение ответа
Нам предстоит добавить самый большую часть кода нашего приложения для обработки полученной информации.
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()
}
}
Когда NSURLConnection получает ответ, вызывается метод didReceiveResponse.
Тут мы просто сбрасываем наши данные, если они были, прописывая self.data = NSMutableData() для создания нового объекта.
После установки соединения, мы начинаем получать данные в методе didReceiveData. Здесь передается аргумент data: NSData, где и находится вся интересующая нас информация. Нам нужно сохранить все полученные в ответе части, поэтому мы присоединяем их к объекту self.data, созданному выше.
Наконец, после того как мы в ответе получили всю информацию, вызывается метод connectionDidFinishLoading, где мы уже можем начать использовать результат.
Мы будем использовать класс NSJSONSerialization для преобразования необработанных данных в полезную информацию в виде объектов словаря NSDictionary.
Теперь, когда мы убедились что получен какой-то ответ от iTunes, простой проверки ключа «results» будет достаточно для того чтобы удостовериться что мы получили именно то что ожидали, поэтому мы можем установить объект self.tableData равным results, а также обратиться к методу таблицы appsTableView.reloadData() для обновления ее содержимого.
Обновление интерфейса Table View UI
Для инициализации Table View в первой статье, нам необходимо было определить две функции: одна возвращает количество строк в таблице, вторая создавала ячейки и описывала их содержимое.
Обновим эти функции, в соответствии с новым функционалом.
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
}
Функция numberOfRowsInSection теперь просто возвращает количество полученных в ответе объектов.
Функция cellForRowAtIndexPath вместо отображения номера строки теперь отображает название объекта, его обложку и стоимость.
Если все хорошо и у вас получилось запустить приложение, возможно вы заметите некоторые «лаги» во время его работы. Это связано с тем, что мы не предусмотрели несколько вещей, которым уделим внимание в следующей статье.
P.S.: После выхода моего перевода, автор несколько обновил урок, немного оптимизировав код. Перевод я постарался привести в соответствие.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Переводить ли следующие статьи из этого цикла?
90.29% Да660
9.71% Нет71
Проголосовал 731 пользователь. Воздержались 98 пользователей.