1

我正在尝试发布 2 个参数(电子邮件:和密码)以从服务器获取包含详细用户信息的响应,我构建 API 来处理此问题并使用 Postman 获得良好响应,但是当我尝试使用 Swift4 new 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() 
}
4

3 回答 3

1

解码 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)
于 2019-11-04T12:07:55.040 回答
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.(CodingKeys in _E33F61CC43E102744E4EF1B7E9D7EDDE).UserInfo], debugDescription: "预期解码 Array 但找到了字典。",基础错误:无))

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

$UserData = json_decode(file_get_contents("php://input"), true);
于 2018-03-21T23:52:36.583 回答
0
  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()
        }
    
    
    }
    
于 2019-10-17T05:52:55.707 回答