无法读取数据,因为它的格式不正确 Xcode 11

Posted

技术标签:

【中文标题】无法读取数据,因为它的格式不正确 Xcode 11【英文标题】:The data couldn’t be read because it isn’t in the correct format Xcode 11 【发布时间】:2019-10-23 04:25:51 【问题描述】:

我收到此错误消息。

“无法读取数据,因为它的格式不正确”

post 请求在 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


【问题讨论】:

您能否展示您的用户模型。因此,您会收到此错误。 刚刚加到最后 NumUser 在您的模型中是 Int 但您在上面分享的响应是在 String 中出现的,这就是您的原因收到此问题是因为 JsonDecoder 无法解析它。我希望你明白我的意思。 对不起,我不明白...我是初学者,除了用户模型之外,我还需要更改其他内容吗? 正如@HammerClass NumUser 提到的,类型应该是String。但是您还有另一个与JSON 结构相关的问题。你得到一个无效的JSON,你可以做的是将api返回的数据打印为print(String(data: unwrappedData, encoding: .utf8)! )并在任何json中验证validator或通过editing包含在你的问题中。 【参考方案1】:

使用这个模型,你会得到你的回应,你的模型有小错误,你的模型和这个模型比较,你会发现。

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

【讨论】:

【参考方案2】:

如果还是有问题

改变:

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

【讨论】:

谢谢,我改变了我的用户结构。我还在控制台中打印了错误,但错误和以前一样,没有更具体的。 “无法读取数据,因为它的格式不正确”

以上是关于无法读取数据,因为它的格式不正确 Xcode 11的主要内容,如果未能解决你的问题,请参考以下文章

无法读取 Info.plist,因为它的格式不正确

在 Swift 4 中使用新的 JSONDecoder 协议时,我得到“无法读取数据,因为它的格式不正确。”错误

无法读取数据,因为它的格式不正确(swift)

Swift 无法读取数据,因为它的格式不正确

错误是无法读取数据,因为它的格式不正确

无法读取数据,因为它的格式不正确