Перевод данной статьи
В этом swift уроке, вы изучите как отправлять HTTP GET запрос в swift. Вы также узнаете как установить параметры запросы и хедеры HTTP запросов и как читать HTTP ответ. Обобщая, этот урок затронет:
- Отправку HTTP GET запроса
- Отправку HTTP хедеров запроса
- Чтение HTTP статуса ответа
- Чтение HTTP пришедших хедеров
- Чтение HTTP ответа тела
- Конвертация JSON HTTP ответа в Swift структуру
Общедоступный Веб сервис RESTful
В этом уроке, я буду использовать общедоступный и бесплатный на момент написания этого уроке веб сервис RESTfull: https://jsonplaceholder.typicode.com. Этот веб сервис позволяет мне отправлять HTTP запросы к нему и получать обратно ответ в виде JSON. На пример, если я открою следующую url в браузере: https://jsonplaceholder.typicode.com/todos/1 то я получу следующий JSON документ:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Отправка HTTP GET запроса
Ниже очень простой пример того как можно отправить HTTP GET запрос в Swift. Пожалуйста обратите внимание на комментарии в коде.
// Create URL
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")
guard let requestUrl = url else { fatalError() }
// Create URL Request
var request = URLRequest(url: requestUrl)
// Specify HTTP Method to use
request.httpMethod = "GET"
// Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check if Error took place
if let error = error {
print("Error took place \(error)")
return
}
// Read HTTP Response Status code
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
// Convert HTTP Response Data to a simple String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
Отправка хедеров в HTTP запросе
Если вам необходимо содержать в HTTP запросе конкретные хедеры, тогда ниже есть приме как вы можете это сделать.
var request = URLRequest(url: requestUrl)
request.httpMethod = "GET"
// Set HTTP Request Header
request.setValue("application/json", forHTTPHeaderField: "Accept")
Вы можете установить более чем один хедер.
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Basic htu574kfj584kfnd84kdlwut92jayebgpylg8md72msgrk", forHTTPHeaderField: "Authorization")
Чтение хедеров HTTP ответа
Как только вы получите HTTP ответ, вы можете прочитать из HTTPURLResponse объекта все HTTP хедеры в ответе за раз или если вы знаете хедеры запроса HTTP, то вы можете прочитать значение каждого указанного хедера.
Чтение всех полей хедеров
let allHeaderFields:[AnyHashable : Any] = response.allHeaderFields
print("All headers: \(allHeaderFields)")
Чтение конкретных хедеров
let contentTypeHeader = response.value(forHTTPHeaderField: "Content-Type")
и здесь то, как вы можете начать использовать HTTP ответ, когда получите его:
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let response = response as? HTTPURLResponse {
// Read all HTTP Response Headers
print("All headers: \(response.allHeaderFields)")
// Read a specific HTTP Response Header by name
print("Specific header: \(response.value(forHTTPHeaderField: "Content-Type") ?? " header not found")")
}
}
task.resume()
Чтение тела HTTP ответа
Когда HTTP ответ получен, вы вероятно хотите прочитать его HTTP тело. Используйте фрагмент кода ниже для конвертации ответа HTTP тела/даты в человеколюбий читаемые строковые значения.
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
ниже выглядит код если вы используете URLSession dataTask:
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
Конвертирование даты в словарь
Если выше HTTP GET запрос вызван, то тело ответа будет содержать строковый JSON который можно легко конвертировать в словарь. Здесь как полученный строковый JSON выглядит:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Давайте сейчас конвертируем его в Swift словарь:
do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
// Print out entire dictionary
print(convertedJsonIntoDict)
// Get value by key
let userId = convertedJsonIntoDict["userId"]
print(userId ?? "userId could not be read")
}
} catch let error as NSError {
print(error.localizedDescription)
}
Конвертация даты в Swift структуру
Мы так же можем конвертировать объект даты в Swift структуру. Для этого мы должны создать Swift структуру которая содержит имена полей которые совпадают с JSON. Вот как выглядит строка JSON из тела ответа. При чтении из ответа HTTP приведенная ниже строка JSON имеет форму данных:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Вот как должна выглядеть наша Swift структура
struct ToDoResponseModel: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
Вот как выглядит конвертация даты в Swift структуру
func parseJSON(data: Data) -> UserResponseModel? {
var returnValue: UserResponseModel?
do {
returnValue = try JSONDecoder().decode(UserResponseModel.self, from: data)
} catch {
print("Error took place\(error.localizedDescription).")
}
return returnValue
}
Давайте все соединим вместе
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else { return }
// Using parseJSON() function to convert data to Swift struct
let todoItem = parseJSON(data: data)
// Read todo item title
guard let todoItemModel = todoItem else { return }
print("Todo item title = \(todoItemModel.title)")
}
task.resume()
Я надеюсь этот урок был полезен для вас. Проверьте другие Swift уроки на этом сайте и вы найдете много полезного кода и примеров.