Метод POST в Swift4 urlSession Decodable не работает (что здесь не так?)

Я пытаюсь опубликовать 2 параметра (электронная почта: и пароль), чтобы получить ответ от сервера с подробной информацией о пользователе, я создаю API для обработки этого и получаю хороший ответ с помощью Postman, но когда я попытался реализовать это с помощью нового URL-адреса Swift4 JSON декодирует и кодирует, он продолжает давать сбой, и я получил ошибку при декодировании данных ответа. это мой ответ JSON при использовании Postman:

{
    "error": "false",
    "message": "downloaded",
    "UserInfo": {
        "id": 5,
        "email": "[email protected]",
        "lastname": "Bence",
        "name": "Mark",
        "phone": "1234567",
        "add1": "333",
        "add2": "444",
        "city": "ott",
        "postalcode": "tttttt"
    }
}

Мой файл структуры:

import UIKit
struct loginPost: Encodable {
    let email: String
    let password: String
}

struct User: Decodable {
    let error: String?
    let message: String?
    let UserInfo: [UserData]

    }

struct UserData: Codable {
    let  id: Int?
    let email: String?
    let lastname: String?
    let name: String?
    let phone: String?
    let add1: String?
    let add2: String?
    let city: String
    let postalcode: String?


}

Моя функция

func downloadJson() {

     let url = URL(string: http://192.168.0.10/api/login_hashed.php)
    guard let downloadURL = url else { return }
    //POST Req


    var request = URLRequest(url: downloadURL)
    request.httpMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")
    let newpost = loginPost(email: "[email protected]", password: "123456")

    do {
        let jsonBody = try JSONEncoder().encode(newpost)

        request.httpBody = jsonBody
        print(jsonBody)
    }catch{
        print("some error")
    }


    URLSession.shared.dataTask(with: request) { data, urlResponse, error in
        guard let data = data, error == nil, urlResponse != nil else {
            print("something is wrong with url")
            return
        }

        print("downloaded..")
        do
        {
            let decoder = JSONDecoder()
            let downloaduser = try decoder.decode(User.self, from: data)
            self.logmessage = downloaduser.message!

            print(self.logmessage)


            DispatchQueue.main.async {

               // self.tableView.reloadData()
            }
        } catch {
            print("something wrong with decode")

        }
        }.resume() 
}

person W Tam    schedule 20.03.2018    source источник
comment
добавьте свой код почтальона и какую ошибку вы получаете через URLSession   -  person deoKasuhal    schedule 20.03.2018
comment
ваш сервер работает нормально?   -  person bestiosdeveloper    schedule 20.03.2018
comment
Да, сервер работает нормально, и я могу запросить POST и получить соответствующий ответ от Почтальона. URL-адрес выполнен, но возвращаемые данные так и не были декодированы, он также используется для перехвата { подпрограммы }. консольная печать - загружена.. - после сеанса Urlsession, а затем печатает - что-то не так с декодированием   -  person W Tam    schedule 21.03.2018


Ответы (3)


Наконец-то разобрался, спасибо. Я просто хочу упомянуть причину этой ошибки и поделиться своим опытом. Основная причина заключается в том, как вы отправляете JSON и получаете входящий ответ. вы должны точно знать, как выглядят данные, чтобы создать свою структуру приемлемым способом. Мои возвращаемые данные - это просто 2 строки текста и массив текста, моя структура была:

import UIKit
struct loginPost: Encodable {
    let email: String
    let password: String
}

struct User: Decodable {
    let error: String?
    let message: String?
    let UserInfo: [UserData]

    }

struct UserData: Codable {
    let  id: Int?
    let email: String?
    let lastname: String?
    let name: String?
    let phone: String?
    let add1: String?
    let add2: String?
    let city: String
    let postalcode: String?


}

моя ошибка в строке 18

  let UserInfo: [UserData]

должен быть

let UserInfo: UserData?

без квадратных скобок. еще один важный момент: всегда старайтесь поймать ошибку декодирования и ее описание, реализуя }catch let JsonErr {, это точно покажет вам, почему декодирование не работает.

в моем случае:

загружен.. что-то не так после загрузки typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [h2h.User.(CodingKeys in _E33F61CC43E102744E4EF1B7E9D7EDDE).UserInfo], debugDescription: "Ожидается декодирование массива, но вместо этого найден словарь.", основная ошибка: ноль))

И убедитесь, что API вашего сервера принимает приложение /json в формате JSON и декодирует то, что вы отправляете, чтобы получить то, что вы ищете; API службы php-кода

$UserData = json_decode(file_get_contents("php://input"), true);
person W Tam    schedule 21.03.2018

Самый простой и легкий способ декодировать json.

ОБЯЗАТЕЛЬНО ПОПРОБУЙТЕ

struct Welcome: Codable {
    let error, message: String?
    let userInfo: UserInfo?

    enum CodingKeys: String, CodingKey {
        case error, message
        case userInfo = "UserInfo"
    }
}

// MARK: - UserInfo
struct UserInfo: Codable {
    let id: Int?
    let email, lastname, name, phone: String?
    let add1, add2, city, postalcode: String?
}

После этого в своем коде, когда вы получите ответ от API, напишите

  let decoder = JSONDecoder()
  let obj = try! decoder.decode(Welcome.self, from: jsonData!)
  Print(obj)
person Ankur Purwar    schedule 04.11.2019

  1. Пункт списка

    Это сработает. Вы создаете модель неправильно?

    struct loginPost: Encodable {
        let email: String
        let password: String
    }
    
    struct Users:Codable {
        var error:String?
        var message:String?
        var UserInfo:UserDetails?
    }
    struct UserDetails:Codable {
        let  id: Int?
        let email: String?
        let lastname: String?
        let name: String?
        let phone: String?
        let add1: String?
        let add2: String?
        let city: String
        let postalcode: String?
    
    }
    
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
         downloadJson()
    
        }
    
        func downloadJson() {
    
            let url = URL(string: "http://192.168.0.10/api/login_hashed.php")
            guard let downloadURL = url else { return }
            //POST Req
    
    
            var request = URLRequest(url: downloadURL)
            request.httpMethod = "POST"
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")
            let newpost = loginPost(email: "[email protected]", password: "123456")
    
            do {
                let jsonBody = try JSONEncoder().encode(newpost)
    
                request.httpBody = jsonBody
                print(jsonBody)
            }catch{
                print("some error")
            }
    
            URLSession.shared.dataTask(with: request) { data, urlResponse, error in
                guard let data = data, error == nil, urlResponse != nil else {
                    print("something is wrong with url")
                    return
                }
    
                print("downloaded..")
                do
                {
                    let decoder = JSONDecoder()
                    let downloaduser = try decoder.decode(Users.self, from: data)
    
    //                self.logmessage = downloaduser.message!
    
    //                print(self.logmessage)
    
    
                    DispatchQueue.main.async {
    
                        // self.tableView.reloadData()
                    }
                } catch {
                    print("something wrong with decode")
    
                }
                }.resume()
        }
    
    
    }
    
person Praveen Reddy    schedule 17.10.2019