Получение ошибки при получении JSON после метода post в swift - PullRequest
0 голосов
/ 04 мая 2018

Я отправляю запрос POST на свой бэкэнд, но получаю эту ошибку:

The given data was not valid JSON.",
underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840
"JSON text did not start with array or object and option to allow
 fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array
or object and option to allow fragments not set.})))

И вот код, который я использую для отправки / извлечения данных:

func fetchDataWithParameters(){

    struct Response: Codable {
        let status: String?
        let error: String?
    }

    let decoder = JSONDecoder()
    HTTP.POST("somelinkhere", parameters: ["date": self.weekDays[self.itemSelectedIndex]]) { response in
        if let error = response.error {
            print("got an error: \(error)")
            return
        }
        do {
            let resp = try decoder.decode(Response.self, from: response.data)
            if let err = resp.error {
                print("got an error: \(err)")
            }
            if let status = resp.status {
                print("completed: \(status)")

            }
        } catch let error {
            print("decode json error: \(error)")
        }
    }
}

Используя мой терминал, я пытаюсь выполнить POST-запрос вручную и получаю следующее:

Admins-MacBook-Pro:hello-world admin$ curl -i -H "Accept: application/json" -H "Content-Type: application/json" somelinkhere
HTTP/1.1 200 OK
Server: openresty/1.9.15.1
Date: Thu, 03 May 2018 23:42:04 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 39
Connection: keep-alive
X-Clacks-Overhead: GNU Terry Pratchett

"{\"name\": \"Timo\", \"age\": \"39\"}"

Это заставляет меня задуматься, что единственно возможной ошибкой может быть то, как я декодирую JSON. Почему еще это будет работать с терминалом? Есть идеи?

Как @patru предложил, я включил печать здесь:

catch let error {
    print(String(data:response.data, encoding: .utf8)!)
    print("decode json error: \(error)")
}

Это был результат:

"{\"name\": \"Mergim\", \"age\": \"39\"}"
decode json error: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

Кажется, что я получаю JSON, как я сделал с curl, но по какой-то причине swift не видит его как действительный JSON? Вот как мой метод записи выглядит в бэкэнде:

@app.route('/', methods=['GET', 'POST'])
def index():

    jsonData = {"name": "Timo", "age": "39"}
    jsonData1 = {"name": "Mergim", "age": "39"}

    if request.method=='GET':
        return json.dumps(jsonData)

    elif request.method=='POST':
        return json.dumps(jsonData1)

РЕДАКТИРОВАТЬ

    jsonData = '{"name": "Timo", "age": "39"}'
    jsonData1 = '{"name": "Mergim", "age": "39"}'

изменено на:

    jsonData = {"name": "Timo", "age": "39"}
    jsonData1 = {"name": "Mergim", "age": "39"}

1 Ответ

0 голосов
/ 04 мая 2018

Это неуловимо, но, хотите верьте, хотите нет, проблема на сервере !

На самом деле ваш код выглядел ... немного не так, но все еще вполне нормально, поэтому я запустил эту игровую площадку:

import Cocoa

let jsonData = "{\"name\": \"Mergim\", \"age\": \"39\"}".data(using: .utf8)!

struct Response: Codable {
    let status: String?
    let error: String?
}

struct NameAge: Codable {
    let name: String
    let age: String
}

do {
    let resp = try JSONDecoder().decode(Response.self, from: jsonData)
    print(resp)
    let na = try JSONDecoder().decode(NameAge.self, from: jsonData)
    print(na)
} catch {
    print(error)
}

print(String(data:jsonData, encoding: .utf8)!)

Поскольку ваша структура Response не совсем соответствует структуре ваших данных, я реализовал NameAge, чтобы получить что-то более подходящее. Тем не менее, оба анализируют, хотя значение Response остается сомнительным. Я тоже был озадачен, пока не проверил ваше сообщение об ошибке: оно жалуется на первый символ в ваших данных! Я наконец добавил последнюю строку на игровой площадке, и проблема стала ясной.

Вы предоставили вашему серверу (я полагаю, что он в ruby ​​или чем-то близком к нему) с действительным String объектом, и он превратил его в соответствующий JSON, который все еще представляет просто String в JSON. Это объясняет двойные кавычки, которые у вас есть, и моя игровая площадка не производит. Вы, вероятно, должны указать свой jsonData как Hash, и сервер преобразует его должным образом (без двойных кавычек). По случайной причине JSONDecoder не хочет декодировать простую JSON-строку, но это то, за что я извиняюсь.

Кстати: вы, вероятно, захотите изменить тип age на Int, как только сможете правильно его передать.

...