Вы находитесь на странице: 1из 22

Сегодня

Networking
Networking
Протокол Передачи Гипертекста (HTTP), один из протоколов стека TCP/IP, был
изначально разработан для публикации и получения HTML страниц и теперь
используется для распределенных информационных систем. HTTP используется во
Всемирной Паутине для передачи данных и является одним из самых широко
применяемых прикладных протоколов

HTTP определяет протокол типа запрос/ответ. Когда клиент, например веб


браузер, посылает сообщение запроса на сервер, HTTP протокол определяет
типы сообщений, используемые клиентом для запроса веб страницы, а также
типы сообщений, применяемые сервером для ответа. Тремя
распространенными типами сообщений являются GET, POST и PUT.

• GET — получение ресурса


• POST — создание ресурса
• PUT — обновление ресурса
• DELETE — удаление ресурса

Для безопасной коммуникации через Интернет используется Безопасный HTTP


протокол (HTTPS), чтобы получать доступ или публиковать информацию на веб
сервере. HTTPS может использовать аутентификацию и шифрование, чтобы
обезопасить данные, когда они перемещаются между клиентом и сервером.
JSON
JSON — текстовый формат обмена данными

формат JSON может быть более подходящим для сериализации сложных


структур. Если говорить о приложениях, то он уместен в задачах обмена
данными между приложением и сервером

Сериализация (в программировании) — процесс перевода какой-либо


структуры данных в последовательность битов. Обратной к операции
сериализации является операция десериализации (структуризации) —
восстановление начального состояния структуры данных из битовой
последовательности.
JSON
В качестве значений в JSON могут быть использованы:
• Объект — это неупорядоченное множество пар ключ:значение,
заключённое в фигурные скобки «{ }». Ключ описывается строкой, между
ним и значением стоит символ «:». Пары ключ-значение отделяются друг
от друга запятыми.
• Массив (одномерный) — это упорядоченное множество значений.
Массив заключается в квадратные скобки «[ ]». Значения разделяются
запятыми.
• Число.
• Литералы true, false и null.
• Строка — это упорядоченное множество из нуля или более
символов юникода, заключенное в двойные кавычки. Символы могут
быть указаны с использованием escape-последовательностей,
начинающихся с обратной косой черты «\» (поддерживаются варианты \",
\\, \/, \t, \n, \r, \f и \b), или записаны шестнадцатеричным кодом в
кодировке Unicode в виде \uFFFF.
JSON
{
"firstName": "Иван",
"lastName": "Иванов",
"address": {
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
"phoneNumbers": [
"812 123-1234",
"916 123-4567"
]
}
URL
URLRequest
URLSession
JSONSerialization
Update UI/DB
URLSession
URLSession это ключевой объект отвечающий за отправление и получение HTTP
запросов. Он создается через URLSessionConfiguration, который бывает в трех
состояниях:
• .default: Создает объект с дефолтными настройками, который использует
глобальный кэш на жестком диске, credential (логин, пароль) и объекты
хранения файлов cookie.
• .ephemeral: Похож на дефолтные настройки за исключением того, что все
данные сеанса хранятся в памяти. Думайте об этом как о «приватном»
сеансе.
• .background: Позволяет сеансу выполнять загрузку задач на сервер или на
клиент в фоновом режиме. Передача продолжается даже когда приложение
приостанавливается само или завершается системой.
URLSessionConfiguration также позволяет вам конфигурировать настройки
сеанса, такие как значения таймаута, политика кеширования и дополнительные
HTTP хедеры (заголовки).
В документации содержится полный список параметров конфигурации.
URLSession
URL Session Programming Guide
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html

Пример создания
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

Сессия будет работать только при wi-fi


ephemeralConfiguration.allowsCellularAccess = false

let ephemeralSessionWiFiOnly = URLSession(configuration: ephemeralConfiguration,


delegate: delegate, operationQueue: operationQueue)
URLSession
URLSessionTask это абстрактный класс, который обозначает объект задачи.
Сеанс создает одну или более задач (task) по извлечению данных и загрузке
файлов на сервер или клиент.
Существует три типа конкретных задач сеанса:
• URLSessionDataTask: Используйте для HTTP GET запросов для извлечения
данных с серверов в память.
• URLSessionUploadTask: Используйте эту задачу для загрузки файлов с диска
на веб-сервис, обычно через HTTP POST или PUT метод.
• URLSessionDownloadTask: Используйте эту задачу для загрузки файлов с
удаленных сервисов во временное хранилище файла.

• dataTaskWithUrl - dataTaskWithRequest
• downloadTaskWithUrl - downloadTaskWithRequest
• uploadTaskWithUrl - uploadTaskWithRequest
URLSession
Различие между dataTaskWithUrl и dataTaskWithRequest, как следует из
названия, заключается в том, что   dataTaskWithUrl требует URL, в то время
как dataTaskWithRequest требует  переменную NSMutableURLRequest.
Различие между URL и NSMutableURLRequest в том, что URL сначала должен
быть инициализирован с вашими требованиями, и ничто не может измениться,
в то время с  NSMutableURLRequest вы можете определить переменную и
тогда устанавливать настройки: значения таймаута, политика кеширования
или использование http методов.
Пример работы с JSON
http://jsonplaceholder.typicode.com
let urlString = URL(string: "http://jsonplaceholder.typicode.com/users/1")

if let url = urlString {


let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print("DataTask error: " + "\(error.localizedDescription)" + "\n")
} else if let usableData = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200 {
print(usableData) //JSONSerialization
}
}
}
task.resume()

Примечание: По-умолчанию для запроса используется метод GET. Если вы


хотите создать задачу использующую POST, PUT или DELETE, создайте
URLRequest с url, установите для HTTPMethod соответствующее свойство, а
затем создайте задачу с URLRequest вместо задачи с URL.
URLRequest

let urlString = "http://jsonplaceholder.typicode.com/users/1"

guard let requestUrl = URL(string:urlString) else { return }

let request = URLRequest(url:requestUrl)

let task = URLSession.shared.dataTask(with: request) {


(data, response, error) in
if let error = error {
print("DataTask error: " + "\(error.localizedDescription)" + "\n")
} else if let usableData = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200 {
print(usableData) //JSONSerialization
}
}

task.resume()
JSONSerialization
Используйте NSJSONSerialization для преобразования JSON в Foundation
объекты и преобразования Foundation объектов в JSON.

• Объект, который будет преобразован в JSON должен иметь


следующие настройки:

• Объектом верхнего уровня является NSArray или NSDictionary.

• Все объекты являются экземплярами NSString, NSNumber, NSArray,


NSDictionary, или NSNull.

• Все dictionary keys являются экземплярами NSString.

• Числа не должны быть NaN или бесконечностью. Могут применяться и


другие правила. Вызов isValidJSONObject(_:) или попытка конверсии - это
окончательные способы определить, может ли данный объект быть
преобразован в данные JSON.

Примечание:
На iOS 7 и более поздних версиях, а также на macOS 10.9 и выше,
NSJSONSerialization это потоко безопасно.
/* Возвращает YES, если данный объект может быть преобразован в
данные JSON, иначе возвращает NO. Объект должен иметь следующие
свойства:
         - Объект верхнего уровня - NSArray или NSDictionary
         - Все объекты: NSString, NSNumber, NSArray, NSDictionary
или NSNull
         - Все dictionary keys - NSStrings
         - NSNumbers не NaN или бесконечность
      Могут применяться другие правила. Вызов этого метода или
попытка преобразования - это окончательные способы определить,
может ли данный объект быть преобразован в данные JSON. */
open class func isValidJSONObject(_ obj: Any) -> Bool

/* Генерировать данные JSON из объекта Foundation. Если объект


не будет выдавать валидный JSON, тогда будет выдано исключение.
Настройка параметра NSJSONWritingPrettyPrinted будет генерировать
JSON с пробелами, предназначенными для обеспечения лучшей
читаемости вывода. Если этот параметр не установлен, то будет
сгенерирован наиболее компактный JSON. Если произойдет ошибка, то
параметр ошибки будет установлен, а возвращаемое значение будет
равно nil. Полученные данные кодируются в UTF-8.
*/
open class func data(withJSONObject obj: Any, options opt:
JSONSerialization.WritingOptions = []) throws -> Data
JSONSerialization

/* Создайте объект Foundation из данных JSON.


Данные должны быть в одной из 5 поддерживаемых кодировок
перечисленных в JSON спецификации: UTF-8, UTF-16LE, UTF-16BE,
UTF-32LE, UTF-32BE.Наиболее эффективным кодированием для
парсинга (синтаксического анализа) является UTF-8, поэтому,
если у вас есть выбор в кодировании данных, переданных этому
методу, используйте UTF-8.
*/
open class func jsonObject(with data: Data, options opt:
JSONSerialization.ReadingOptions = []) throws -> Any
JSONEncoder and JSONDecoder in Swift 4
Swift 4 представил классы JSONEncoder и JSONDecoder которые могут с
легкостью конвертировать объекты в encoded JSON представление.

Обратите внимание на использование нового протокола Codable, который делает


кодировку и декодирование структуры языка.
URLSession
URLSession(configuration: .ephemeral, delegate: self, delegateQueue:
OperationQueue.main)

Если вы используете пользовательский делегат для извлечения данных,


делегат должен реализовать по крайней мере следующие методы:
• URLSession:dataTask:didReceiveData: предоставляет данные из
запроса к вашей задаче, по одной части за раз.
• URLSession:task:didCompleteWithError: указывает вашей задаче, что
данные были полностью получены.
URLSession
URLSessionDownloadDelegate
Существует несколько делегатов-протоколв перечисленные в
URLSession documentation. URLSessionDownloadDelegate
обрабатывает события, специфичные для задач загрузки, на
уровне задачи.

URLSessionDownloadDelegate:
extension SearchViewController: URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL) {
print("Finished downloading to \(location).")
}
}
URLSession
На высоком уровне загрузка файла аналогична извлечению данных. В
вашем приложении должны быть реализованы следующие методы
делегирования:
• URLSession:downloadTask:didFinishDownloadingToURL:
Предоставляет вашему приложению URL для временного файла, в
котором хранится загруженный контент. Важно: перед тем как этот
метод вернется, он должен либо открыть файл для чтения, либо
перенести его в постоянное место. Когда этот метод возвращается,
временный файл удаляется, если он все еще существует в исходном
местоположении.

URLSession:downloadTask:didWriteData:totalBytesWritten:totalB
ytesExpectedToWrite: Предоставляет вашему приложению
информацию о состоянии загрузки.
• URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:
Сообщает вашему приложению, что его попытка возобновить ранее
неудачную загрузку прошла успешно.
• URLSession:task:didCompleteWithError: Сообщает вашему
приложению, что загрузка не удалась.
Upload Data
Ваше приложение может предоставить контент тела запроса для HTTP
POST запроса тремя способами: как объект NSData, как файл или как
поток. В общем:
• Используйте объект NSData, если ваше приложение уже имеет данные в
памяти и не имеет никаких причин избавляться от них.
• Используйте файл, если контент, который вы загружаете, существует в
виде файла на диске, если вы выполняете фоновый перенос, или если вы
хотите записать его на диск, чтобы он мог освободить память, связанную с
этими данными.
• Используйте поток (stream), если вы получаете данные по сети.
Upload Data
Чтобы загрузить содержимое тела с помощью объекта NSData, ваше
приложение вызывает или метод uploadTaskWithRequest:fromData: или
uploadTaskWithRequest:fromData:completionHandler: для создания
задачи загрузки и предоставления данных тела запроса через параметр
fromData.
let textFileURL = URL(fileURLWithPath: "/path/to/file.txt")

if let data = try? Data(contentsOf: textFileURL) {

if let url = URL(string: "https://www.example.com/") {


var mutableRequest = MutableURLRequest(url: url)
mutableRequest.httpMethod = "POST"
mutableRequest.setValue("\(data.count)", forHTTPHeaderField: "Content-Length")
mutableRequest.setValue("text/plain", forHTTPHeaderField: "Content-Type")

let uploadTask = URLSession.shared.uploadTask(with: mutableRequest as URLRequest,


from: data)

uploadTask.resume()

Вам также может понравиться