Запрос POST с URLSession в Swift в приложении командной строки

Я пытаюсь отправить 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()

Дайте определение «это не работает». Что находится в теле ответа? Какой был код состояния HTTP?

Rob 09.12.2020 16:42

В теле находится: {"key": "83fcbf65-1d2c-4051-b37f-5935e8fc7768", "source": {"dialect": "en", "text": "Как дела?"}, "target" : {"диалект": "эс"}}

Aidn 09.12.2020 16:49

@Rob Нет ошибки. ответ статуса 200

Leo Dabus 09.12.2020 16:50

@Aidn Ваш фактический ответ {"source": {"text": "How are you?", "dialect": "en"}, "target": {"dialect": "es", "text": "\u00bfC\u00f3mo est\u00e1s?"}, "times": {"total_time": 0.041}}

Leo Dabus 09.12.2020 16:51

То есть он говорит вам «¿Cómo estás?», что правильно.

Rob 09.12.2020 16:53

Как вы получаете фактический ответ @LeoDabus?

Aidn 09.12.2020 16:53

Я не понимаю "он сразу останавливается". Это на детской площадке или в приложении?

Rob 09.12.2020 16:53

Просто приложение командной строки

Aidn 09.12.2020 16:54

Приложение командной строки не будет ждать завершения фонового запроса URLSession. Это закрытие вызывается асинхронно (т.е. позже).

Rob 09.12.2020 16:55

Я имею в виду, что он должен напечатать ответ, не так ли?

Aidn 09.12.2020 16:55

(ответ как? HTTPURLResponse)?.statusCode

Leo Dabus 09.12.2020 16:55

@ Ларме, да. Спасибо. Он печатает ответ.

Aidn 09.12.2020 17:02

Это предложенный комментарий, указанный Робом stackoverflow.com/questions/65219810/… Я просто ищу для него похожий вопрос.

Larme 09.12.2020 17:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
13
364
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В большинстве приложений есть «цикл выполнения», который постоянно работает, реагируя на действия пользователя и поддерживая приложение в рабочем состоянии до тех пор, пока пользователь не завершит его явным образом. В этом сценарии мы можем инициировать асинхронный сетевой запрос, будучи уверенными, что цикл выполнения поддерживает наше приложение, и когда приходит сетевой ответ, вызывается закрытие нашего обработчика завершения.

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

Однако вы можете заставить приложение командной строки дождаться завершения запроса перед завершением, например.

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()

Теперь этот метод (ожидание в основном потоке, тем самым блокируя этот поток) является очень плохой практикой в ​​​​стандартных приложениях, поскольку он блокирует основной поток во время выполнения сетевого запроса. В типичном приложении блокировка основного потока приведет к зависанию пользовательского интерфейса, предлагая нестандартный пользовательский интерфейс (и ОС может даже убить приложение из-за того, что оно не отвечает). Обычно мы никогда не блокируем основной поток.

Но в приложении командной строки, где вы часто не беспокоитесь о изящном и отзывчивом пользовательском интерфейсе, блокировка основного потока не является проблемой, и вышеперечисленное может поддерживать работу приложения во время выполнения сетевого запроса.

Другие вопросы по теме