我正在创建一个应用程序,其中它从API服务器提取viewModel.itemClickedEvent.observe(this, Observer {isItemClicked->
if(isItemClicked){
// Do your changes
}
})
,并且将显示为PatientList
。检查后,它返回TableView
状态代码,但出现200
错误。但是,当我签入 Postman 时,它会返回invalidJSON
状态代码并正确提取记录。我很困惑我的代码的哪一部分会导致错误,因为我是新手。我正在寻求帮助以解决该问题。以下是我的示例代码供您参考。提前非常感谢您。
Patient.swift
200
APIService.swift
struct Patient: Codable {
let hospitalNumber: Int
let patientName: String
let totalAmount: Double
enum CodingKeys: String, CodingKey {
case hospitalNumber = "hospitalNumber"
case patientName = "patientName"
case totalAmount = "totalAmount"
}
}
Controller.swift
struct PatientList {
typealias getPatientListTaskCompletion = (_ patientListperPayout: [Patient]?, _ error: NetworkError?) -> Void
static func getPatientList(doctorNumber: Int, periodId: Int, completion: @escaping getPatientListTaskCompletion) {
guard let patientPerPayoutURL = URL(string: "\(Endpoint.Patient.patientPerPayout)?periodId=\(periodId)&doctorNumber=\(doctorNumber)") else {
completion(nil, .invalidURL)
return
}
let sessionManager = Alamofire.SessionManager.default
sessionManager.session.getAllTasks { (tasks) in
tasks.forEach({ $0.cancel() })
}
Alamofire.request(patientPerPayoutURL, method: .get, encoding: JSONEncoding.default).responseJSON { (response) in
guard HelperMethods.reachability(responseResult: response.result) else {
completion(nil, .noNetwork)
return
}
guard let statusCode = response.response?.statusCode else {
completion(nil, .noStatusCode)
return
}
switch(statusCode) {
case 200:
guard let jsonData = response.data else{
completion(nil, .invalidJSON)
print(statusCode)
return
}
let decoder = JSONDecoder()
do {
let patientListArray = try decoder.decode([Patient].self, from: jsonData)
let sortedPatientListArray = patientListArray.sorted(by: { $0.patientName < $1.patientName })
completion(sortedPatientListArray, nil)
}catch{
completion(nil, .invalidJSON)
print(statusCode)
}
case 400:
completion(nil, .badRequest)
case 404:
completion(nil, .noRecordFound)
default:
print("UNCAPTURED STATUS CODE FROM getPatientList\nSTATUS CODE: \(statusCode)")
completion(nil, .uncapturedStatusCode)
}
}
}
JSON响应
var patientList: [Patient]! {
didSet {
performSegue(withIdentifier: patientListIdentifier, sender: self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.latestCreditedAmountTableView.dataSource = self
self.latestCreditedAmountTableView.delegate = self
configureTableViewCell()
showTotalCreditedAmount()
getDoctorPayoutSummary(doctorNumber: doctorNumber)
}
func getDoctorPayoutSummary(doctorNumber: Int) {
self.payoutSummary = payoutSummaryDetails
self.taxRateVatRateLabel.text = "\(self.payoutSummary.taxRate) / \(self.payoutSummary.vatRate)"
self.getPatientList()
self.latestCreditedAmountTableView.reloadData()
return
}
func getPatientList() {
APIService.PatientList.getPatientList(doctorNumber: doctorNumber, periodId: currentRemittance.periodId) { (patientListArray, error) in
guard let patientListPerPayout = patientListArray, error == nil else {
if let networkError = error {
switch networkError {
case .noRecordFound:
let alertController = UIAlertController(title: "No Record Found", message: "You don't have current payment remittance", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true, completion: nil)
case .noNetwork:
let alertController = UIAlertController(title: "No Network", message: "\(networkError.rawValue)", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true, completion: nil)
default:
let alertController = UIAlertController(title: "Error", message: "There is something went wrong. Please try again", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default))
self.present(alertController, animated: true, completion: nil)
}
}
return
}
self.patientList = patientListPerPayout
return
}
}
答案 0 :(得分:1)
您的JSON响应表明,某些字段可以为空-至少if (!ModelState.IsValid) {
return OnGet();
}
和if ($num_rows > 0 ) {
print "<table border=0>";
while ( $a_row = mysqli_fetch_row($result) ) {
print "<tr>\n";
foreach ($a_row as $field)
print "\t<td>$field</td>\n";
print "\t<td><a href='cart.php?id=$your_product_id'>Add to cart</a></td>\n";
print "</tr>";
}
print "</table>";
}
。 hospitalNumber
也是JSON中的字符串-感谢@Don指出。您的patientName
还应该能够通过使映射的字段也可以为空来应对这些可为空的情况。即
hospitalNumber
如果struct
也可以为null,则需要执行相同的操作。当然,在任何情况下API是否正确返回空值都是另一个问题-可能需要解决空医院号或医院名称的作用。
请确保在使用字段时不要强行打开它们。
答案 1 :(得分:0)
只需在模型类中进行以下更改。将模型类变量定义为optional
,这不是API所必需的。
struct Patient: Codable {
var hospitalNumber: String?
let patientName: String?
let totalAmount: Double?
enum CodingKeys: String, CodingKey {
case hospitalNumber = "hospitalNumber"
case patientName = "patientName"
case totalAmount = "totalAmount"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let hospitalNumb = try container.decode(Int?.self, forKey: .hospitalNumber) {
hospitalNumber = String(hospitalNumb)
} else {
hospitalNumber = try container.decode(String.self, forKey: .hospitalNumber)
}
patientName = try container.decode(String.self, forKey: .patientName)
totalAmount = try container.decode(Double.self, forKey: .totalAmount)
}
}
注意:
Codable
或Decodable
不起作用,如果同一键的类型不同,或者您可以说该类型不同于指定的类型。