Ошибка 400 при отправке почтового запроса на локальный сервер в Swift

Я пытаюсь сделать запрос HTTP POST на локальный сервер, но когда я делаю вызов, я получаю ошибку 400 на стороне сервера, поэтому я считаю, что есть проблема в том, как я делаю запрос в коде Swift . Я не уверен, правильно ли я устанавливаю тело JSON, но буду очень признателен за любую помощь. Заранее спасибо!

быстрый код:

    let url = URL(string: "http://127.0.0.1:5000/get-friends")!
    var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10)
    request.httpMethod = "POST"
    let tempIdDictionary: [String: Int] = ["user_id": 17]
    let jsonBody = try? JSONSerialization.data(withJSONObject: tempIdDictionary, options: .fragmentsAllowed)
    request.httpBody = jsonBody
    
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        guard let data = data else { return }
        do {
            let friendList = try JSONDecoder().decode(FriendList.self, from: data)
        } catch let jsonErr {
            print(jsonErr)
        }
    }
    task.resume()

структура для хранения данных json:

struct FriendList: Codable {
    let result: [Int]
}

это ошибка, которая появляется в Swift, когда я пытаюсь сделать запрос:

dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))

Запрос почтальона


person Jonathan Yuan    schedule 28.07.2020    source источник


Ответы (1)


Обновление: из снимка экрана, который вы только что добавили, видно, что вам нужно передавать данные как form-data вместо json. Вот как вы это делаете, добавьте следующие расширения:

extension URLRequest {

    struct MultipartFile {
        var data: Data
        var mimeType, filename: String
    }

    mutating func multipartFormData(
        parameters: [String: String] = [:],
        files: [MultipartFile] = []) {

        var body = Data()
        let boundary = "Boundary-\(UUID().uuidString)"
        let boundaryPrefix = "--\(boundary)\r\n"

        for (key, value) in parameters {
            body + boundaryPrefix
            body + "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n"
            body + "\(value)\r\n"
        }

        for file in files {
            body + boundaryPrefix
            body + "Content-Disposition: form-data; name=\"file\"; filename=\"\(file.filename)\"\r\n"
            body + "Content-Type: \(file.mimeType)\r\n\r\n"
            body.append(file.data)
            body + "\r\n"
        }

        body + "--".appending(boundary.appending("--"))

        httpBody = body
        httpMethod = httpMethod == "GET" ? "POST" : httpMethod
        setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    }
}

extension Data {

    static func + (data: inout Data, string: String) {
        data.append(Data(string.utf8))
    }
}

Затем измените запрос следующим образом:

request.httpMethod = "POST"
request.multipartFormData(parameters: ["user_id": 17])
// remove the `JSON` body part
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
person Frankenstein    schedule 28.07.2020
comment
Проверьте свой запрос на почтальоне, чтобы узнать, не связана ли проблема с API. - person Frankenstein; 28.07.2020
comment
Добавьте скриншот запроса почтальона к своему сообщению. - person Frankenstein; 29.07.2020
comment
Хорошо, я добавил скриншот в конец исходного сообщения. - person Jonathan Yuan; 29.07.2020
comment
Итак, проблема в том, что вы передаете данные сыну, но вам нужно передать их как данные формы. - person Frankenstein; 29.07.2020
comment
ах, я вижу, вы знаете, как бы я подошел к этому? Извините, я не знаком с данными формы, я не знал, что есть разница - person Jonathan Yuan; 29.07.2020
comment
Я вижу это сейчас. Спасибо большое за вашу помощь! - person Jonathan Yuan; 29.07.2020