Я пытаюсь отправить HTTP-запрос методом POST в приложении командной строки. Использование JSON в качестве тела запроса. Я использую session.uploadTask
для отправки этого запроса и использую данные JSON, сериализованные из простых Dictionary
. Может я что-то пропустил, но это не работает. Я даже пытался написать свой запрос на консоль, и он выглядит хорошо -> это тот же формат, который нужен API iTranslate.
//creating new session
let session = URLSession.shared
let url = URL(string: "https://api.itranslate.com/translate/v1")!
//setting httpMethod to POST
var request = URLRequest(url: url)
request.httpMethod = "POST"
//setting header
request.setValue("application/json", forHTTPHeaderField: "content-type")
//dictionary with json
let json = ["key": "...", "source": ["dialect":"en", "text": "How are you?"], "target": ["dialect": "es"]] as [String : Any]
//serialization from json to jsonData
let jsonData = try! JSONSerialization.data(withJSONObject: json, options: [])
let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print(dataString)
}
}
task.resume()
В теле находится: {"key": "83fcbf65-1d2c-4051-b37f-5935e8fc7768", "source": {"dialect": "en", "text": "Как дела?"}, "target" : {"диалект": "эс"}}
@Rob Нет ошибки. ответ статуса 200
@Aidn Ваш фактический ответ {"source": {"text": "How are you?", "dialect": "en"}, "target": {"dialect": "es", "text": "\u00bfC\u00f3mo est\u00e1s?"}, "times": {"total_time": 0.041}}
То есть он говорит вам «¿Cómo estás?», что правильно.
Как вы получаете фактический ответ @LeoDabus?
Я не понимаю "он сразу останавливается". Это на детской площадке или в приложении?
Просто приложение командной строки
Приложение командной строки не будет ждать завершения фонового запроса URLSession
. Это закрытие вызывается асинхронно (т.е. позже).
Я имею в виду, что он должен напечатать ответ, не так ли?
(ответ как? HTTPURLResponse)?.statusCode
@ Ларме, да. Спасибо. Он печатает ответ.
Это предложенный комментарий, указанный Робом stackoverflow.com/questions/65219810/… Я просто ищу для него похожий вопрос.
В большинстве приложений есть «цикл выполнения», который постоянно работает, реагируя на действия пользователя и поддерживая приложение в рабочем состоянии до тех пор, пока пользователь не завершит его явным образом. В этом сценарии мы можем инициировать асинхронный сетевой запрос, будучи уверенными, что цикл выполнения поддерживает наше приложение, и когда приходит сетевой ответ, вызывается закрытие нашего обработчика завершения.
С другой стороны, в приложении командной строки, когда оно доходит до конца кода, приложение просто завершает работу, не давая асинхронному сетевому запросу возможности ответить, и закрытие никогда не будет вызвано.
Однако вы можете заставить приложение командной строки дождаться завершения запроса перед завершением, например.
let semaphore = DispatchSemaphore(value: 0)
let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print(dataString)
}
semaphore.signal()
}
task.resume()
semaphore.wait()
Теперь этот метод (ожидание в основном потоке, тем самым блокируя этот поток) является очень плохой практикой в стандартных приложениях, поскольку он блокирует основной поток во время выполнения сетевого запроса. В типичном приложении блокировка основного потока приведет к зависанию пользовательского интерфейса, предлагая нестандартный пользовательский интерфейс (и ОС может даже убить приложение из-за того, что оно не отвечает). Обычно мы никогда не блокируем основной поток.
Но в приложении командной строки, где вы часто не беспокоитесь о изящном и отзывчивом пользовательском интерфейсе, блокировка основного потока не является проблемой, и вышеперечисленное может поддерживать работу приложения во время выполнения сетевого запроса.
Дайте определение «это не работает». Что находится в теле ответа? Какой был код состояния HTTP?