【问题标题】:POST method in Swift4 urlSession Decodable not working(What goes wrong here?)Swift4 url​​Session Decodable 中的 POST 方法不起作用(这里出了什么问题?)
【发布时间】:2018-03-20 04:31:29
【问题描述】:

我正在尝试发布 2 个参数(电子邮件:和密码)以从服务器获取包含详细用户信息的响应,我构建 API 来处理此问题并使用 Postman 获得良好响应,但是当我尝试使用Swift4 新的 urlsession JSON 解码和编码,它一直失败,我在解码响应数据时出错。 这是我在使用 Postman 时的 JSON 响应:

{
    "error": "false",
    "message": "downloaded",
    "UserInfo": {
        "id": 5,
        "email": "abc@hotmail.com",
        "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: "abc@hotmail.com", 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() 
}

【问题讨论】:

  • 添加您的邮递员代码以及您通过 URLSession 遇到的错误
  • 你的服务器工作正常吗?
  • 是的,服务器工作正常,我可以请求 POST 并从 Postman 获得相应的响应。 URLseesion 执行但返回数据从未解码,它也去 catch {routine }。控制台打印 - “下载..” - 在 Urlsession 之后,随后打印 - “解码有问题”

标签: swift4 urlsession jsondecoder


【解决方案1】:

终于弄明白了,谢谢。 我只想提一下这个错误的原因并分享我的经验。 主要原因是您发送 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.(_E33F61CC43E102744E4EF1B7E9D7EDDE 中的 CodingKeys).UserInfo], debugDescription: "预期解码 Array 但发现了一个 字典代替。”,基础错误:无))

并确保您的服务器 API 接受 JSON 格式的 application/json 和 解码您发送的内容以接收您要查找的内容; php代码服务API

$UserData = json_decode(file_get_contents("php://input"), true);

【讨论】:

    【解决方案2】:

    解码 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)
    

    【讨论】:

      【解决方案3】:
      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: "abc@hotmail.com", 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()
            }
        
        
        }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-29
        • 2011-02-25
        • 2012-11-21
        • 1970-01-01
        • 1970-01-01
        • 2012-12-06
        相关资源
        最近更新 更多