无法读取数据,因为它的格式不正确 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的主要内容,如果未能解决你的问题,请参考以下文章