由于数据格式不正确,因此无法读取数据Xcode 11

时间:2019-10-23 04:25:51

标签: php json swift xcode

我收到此错误消息。

“由于格式不正确,无法读取数据”

发布请求在PostMan中有效,因此错误必须在我的代码中,而不是在我的数据库中。

我尝试了几件事,但是我是一个初学者,我有点卡在这里...

我有如下所示的json数据


{  "error":1, "NumUser":"179", "cFirstname":"test", "cEmail":"a@a.com", "cPassword":"$2y$10$uV.YUtyfyiDzUT/2HYS/dOmIg7vNVPrwNhcmbg5iFvHlVi1rEThuC"  } 

我使用swift从json中获取数据

//
//  NetworkingService.swift
//  Database Login
//
//  Created by Kyle Lee on 2/17/19.
//  Copyright © 2019 Kilo Loco. All rights reserved.
//

import Foundation

enum MyResult<T, E: Error> {

    case success(T)
    case failure(E)
}

class NetworkingService {

    let baseUrl = "https://zzzway.com/appMango"

    func handleResponse(for request: URLRequest,
                        completion: @escaping (Result<User, Error>) -> Void) {

        let session = URLSession.shared

        let task = session.dataTask(with: request) { (data, response, error) in

            DispatchQueue.main.async {

                guard let unwrappedResponse = response as? HTTPURLResponse else {
                    completion(.failure(NetworkingError.badResponse))
                    return
                }

                print(unwrappedResponse.statusCode)

                switch unwrappedResponse.statusCode {

                case 200 ..< 300:
                    print("success")

                default:
                    print("failure")
                }

                if let unwrappedError = error {
                    completion(.failure(unwrappedError))
                    return
                }

                if let unwrappedData = data {

                    do {
                        let json = try JSONSerialization.jsonObject(with: unwrappedData, options: [])
                        print(json)

                        if let user = try? JSONDecoder().decode(User.self, from: unwrappedData) {
                            completion(.success(user))

                        } else {
                            let errorResponse = try JSONDecoder().decode(ErrorResponse.self, from: unwrappedData)
                            completion(.failure(errorResponse))
                        }

                    } catch {
                        completion(.failure(error))
                    }
                }
            }
        }

        task.resume()
    }

    func request(endpoint: String,
                 parameters: [String: Any],
                 completion: @escaping (Result<User, Error>) -> Void) {

        guard let url = URL(string: baseUrl) else {
            completion(.failure(NetworkingError.badUrl))
            return
        }

        var request = URLRequest(url: url)

        var components = URLComponents()

        var queryItems = [URLQueryItem]()

        for (key, value) in parameters {

            let queryItem = URLQueryItem(name: key, value: String(describing: value))
            queryItems.append(queryItem)
        }

        components.queryItems = queryItems

        // username=kiloloco&password=pass123
        let queryItemData = components.query?.data(using: .utf8)

        request.httpBody = queryItemData
        request.httpMethod = "POST"
        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

        handleResponse(for: request, completion: completion)
    }

    func request(endpoint: String,
                 loginObject: Login,
                 completion: @escaping (Result<User, Error>) -> Void) {

        guard let url = URL(string: baseUrl) else {
            completion(.failure(NetworkingError.badUrl))
            return
        }

        var request = URLRequest(url: url)

        do {
            let loginData = try JSONEncoder().encode(loginObject)
            request.httpBody = loginData

        } catch {
            completion(.failure(NetworkingError.badEncoding))
        }

        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        handleResponse(for: request, completion: completion)
    }


}

enum NetworkingError: Error {
    case badUrl
    case badResponse
    case badEncoding
}

//
//  LoginViewController.swift
//  Database Login
//
//  Created by Kyle Lee on 2/17/19.
//  Copyright © 2019 Kilo Loco. All rights reserved.
//

import UIKit

class LoginViewController: UITableViewController {

    override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }

    @IBOutlet weak var usernameTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!

    let alertService = AlertService()
    let networkingService = NetworkingService()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.keyboardDismissMode = .onDrag
    }

    @IBAction func didTapLoginButton() {

        guard
            let cEmail = usernameTextField.text,
            let cPassword = passwordTextField.text,
            let Connecter:String="Connecter"
            else { return }


//        formDataRequest(username: username, password: password)

        jsonRequest(cEmail: cEmail, cPassword: cPassword, Connecter: Connecter)
    }

    func formDataRequest(cEmail: String, cPassword: String, Connecter: String) {
        let parameters = ["email": cEmail,
                          "password": cPassword,
                          "loginbutton": Connecter]

        networkingService.request(endpoint: "/login.php", parameters: parameters) { [weak self] (result) in

            switch result {

            case .success(let user): self?.performSegue(withIdentifier: "loginSegue", sender: user)

            case.failure(let error):

                guard let alert = self?.alertService.alert(message: error.localizedDescription) else { return }
                self?.present(alert, animated: true)
            }
        }
    }

    func jsonRequest(cEmail: String, cPassword: String, Connecter: String) {

        let login = Login(cEmail: cEmail, cPassword: cPassword, Connecter: Connecter)

        networkingService.request(endpoint: "/login.php", loginObject: login) { [weak self] (result) in

            switch result {

            case .success(let user): self?.performSegue(withIdentifier: "loginSegue", sender: user)

            case.failure(let error):

                guard let alert = self?.alertService.alert(message: error.localizedDescription) else { return }
                self?.present(alert, animated: true)
            }
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let mainAppVC = segue.destination as? MainAppViewController, let user = sender as? User {

            mainAppVC.user = user
        }
    }
}
import Foundation

struct User: Decodable {

    let error:Int
    let NumUser: Int
    let cFirstname: String
    let cEmail: String
    let cPassword: String

}

2 个答案:

答案 0 :(得分:0)

使用此模型,您将得到答复,您的模型中有一个小错误,将您的模型与此模型进行比较,您会发现。

struct User: Codable {
let error: Int?
let numUser, cFirstname, cEmail, cPassword: String?

enum CodingKeys: String, CodingKey {
    case error
    case numUser = "NumUser"
    case cFirstname, cEmail, cPassword
}

}

答案 1 :(得分:0)

如果您仍然有问题

更改:

struct User: Decodable {

    let error:Int
    let NumUser: Int
    let cFirstname: String
    let cEmail: String
    let cPassword: String

}

收件人:

struct User: Decodable {

    let error:Int
    let NumUser: String
    let cFirstname: String
    let cEmail: String
    let cPassword: String

}

这是您的JSON的外观,它必须与您的模型匹配。

{
    "error": Int,
    "NumUser": String,
    "cFirstname": String,
    "cEmail": String,
    "cPassword": String
}

此外,在jsondecoder do catch中,您还会在catch中收到一条错误消息,该错误告诉您类似以下内容:

Swift.DecodingError.typeMismatch(Swift.String, 
Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "NumUser", 
intValue: nil)], debugDescription: "Expected to decode Int but found an String 
instead.", underlyingError: nil)))

实际上揭示出什么地方出了问题。您可以通过print(error.localizedDescription)显示它,或者如果您在断点处停止,则可以在控制台中使用po error.localizedDescription