Ошибка отправки POST-запроса от Swift - PullRequest
0 голосов
/ 06 июня 2019

По сути, мне нужно отправить запрос POST в API, который ищет значение параметра для "value" В моем приложении Swift есть переменная, которая называется testPOST и содержит значение, которое ищет API:

У меня проблемы с пониманием, почему не работает следующий код?

fileprivate func fetchJSON(){
    var urlString =  URLRequest(url: URL(string: "https://example.com/example/example.php")!)
    guard let url = URL(string: urlString) else { return }
    urlString.httpMethod = "POST"
    let postString = "value=\(testPOST)"
    URLRequest.httpBody = postString.data(using: .utf8)
    URLSession.shared.dataTask(with: url) { (data, _, error) in
        DispatchQueue.main.async {
            if let error = error {
                print("Failed to fetch data from url", error)
                return
            }
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                // Swift 4.1

                self.structure = try decoder.decode([ScheduleStructure].self, from: data)

                self.tableView.reloadData()

            } catch let jsonError {
                print("Failed to decode json", jsonError)
            }

        }
        }.resume()
}

UPDATE:

Я не получаю никаких сообщений об ошибках, но я также не получаю обратно никаких данных JSON, ScheduleStructure - это кодируемая структура, которая у меня есть, но, похоже, она не читается.

import UIKit

struct ScheduleStructure: Codable {
    let customer: String
    let PickedUpNUM: String
    let DeliveryNUM: String

}

Мне просто нужен способ POST-значения для API, чтобы он возвращал данные JSON. Единственная проблема, с которой я сталкиваюсь - это отправка данных из приложения и возвращение данных.

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Измените начало вашей функции на

guard let url = URL(string: "https://example.com/example/example.php") else {
    return
}
var request =  URLRequest(url: url)
request.httpMethod = "POST"
let postString = "value=\(testPOST)"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data, _, error) in

Вы дважды создали свой объект url и обработали запрос как строку

1 голос
/ 06 июня 2019

Не стесняйтесь принять ответ Йоакима , который выявил синтаксические проблемы, но я хотел сделать еще одно замечание.В частности, ваш запрос не будет работать или не будет работать должным образом, если testPOST содержит какие-либо зарезервированные символы (например, пробел, &, + и т. Д.).Если вы не знаете, что testPOST никогда не может содержать такие символы, следует кодировать значение в процентах при построении запроса, например:

func fetchJSON() {
    guard
        let url = URL(string: "https://example.com/example/example.php"),
        let value = testPOST.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
    else { return }

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = "value=\(value)".data(using: .utf8)

    URLSession.shared.dataTask(with: request) { data, _, error in
        DispatchQueue.main.async {
            // ...
        }
    }.resume()
}

Где

extension CharacterSet {
    static let urlQueryValueAllowed: CharacterSet = {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="

        var allowed = CharacterSet.urlQueryAllowed
        allowed.remove(charactersIn: generalDelimitersToEncode + subDelimitersToEncode)
        return allowed
    }()
}

Кстати, это такжеРекомендуется (хотя часто и не требуется) устанавливать несколько заголовков, в частности Content-Type (указание, как кодируется запрос) и Accept (как клиент ожидает, что ответ будет закодирован).

request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")

Ваш веб-сервис явно не учитывает эти заголовки, но многие веб-сервисы делают.Кроме того, это делает цель вашего кода явной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...