我收到此错误消息。
“由于格式不正确,无法读取数据”
发布请求在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
}
答案 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