我有一个应用,其中需要使用API
从alamofire function
提取数据。以下是我需要抽取的示例json
。它应显示在CollectionCell
中。我在自定义收集单元格中使用了garlandView
吊舱。但不幸的是,它总是返回fatal error: unexpectedly found nil while unwrapping an Optional value
错误。以下是我的示例json
:
{
"chargeId": "33fbbbd0-2e33-11e9-a2cb-8a27ecbbcb73",
"chargeDate": "2019-02-12T03:28:44.000",
"vatRate": "NON-VAT",
"taxRate": 0.05,
"policyGroup": "Patient Participation",
"itemDescription": "Ecg at er/icu df",
"scdFlag": 0,
"amounts": null,
"scdDiscounts": 0,
"othDiscounts": 4.54,
"adjustment": 0,
"pfBill": 222.46,
"vatAmount": 0,
"taxableAmount": 11.12,
"merchantDiscount": 0,
"creditedAmount": 211.3,
"chargeAmount": null,
"previousCredits": null
}
PatientProcedure.swift
struct PatientProcedure: Codable {
let id: String?
let chargeDate: String?
let vatRate: String?
let taxRate: Double?
let policyGroup: String?
let itemDescription: String?
let amounts: Double?
let scdDiscounts: Double?
let otherDiscounts: Double?
let adjustment: Double?
let pfBill: Double?
let vatAmount: Double?
let taxableAmount: Double?
let merchantDiscount: Double?
let creditedAmount: Double?
let chargeAmount: Double?
let previousCredits: Double?
enum CodingKeys: String, CodingKey {
case id = "chargeId"
case chargeDate = "chargeDate"
case vatRate = "vatRate"
case taxRate = "taxRate"
case policyGroup = "policyGroup"
case itemDescription = "itemDescription"
case amounts = "amounts"
case scdDiscounts = "scdDiscounts"
case otherDiscounts = "othDiscounts"
case adjustment = "adjustment"
case pfBill = "pfBill"
case vatAmount = "vatAmount"
case taxableAmount = "taxableAmount"
case merchantDiscount = "merchantDiscount"
case creditedAmount = "creditedAmount"
case chargeAmount = "chargeAmount"
case previousCredits = "previousCredits"
}
APIService.swift
typealias getPatientProcedureTaskCompletion = (_ patientProcedure: PatientProcedure?, _ error: NetworkError?) -> Void
static func getPatientProcedureDetails(chargedId: String, completion: @escaping getPatientProcedureTaskCompletion) {
guard let formattedValue = chargedId.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
return
}
guard let patientProcedureURL = URL(string: "\(Endpoint.Patient.patientProcedureDetails)/\(formattedValue)") else {
completion(nil, .invalidURL)
return
}
let sessionManager = Alamofire.SessionManager.default
sessionManager.session.getAllTasks { (tasks) in
tasks.forEach({ $0.cancel() })
}
Alamofire.request(patientProcedureURL, method: .get, encoding: JSONEncoding.default).responseJSON { (response) in
print(patientProcedureURL)
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)
return
}
let decoder = JSONDecoder()
do {
let patientDetailsPayout = try decoder.decode(PatientProcedure.self, from: jsonData)
completion(patientDetailsPayout, nil)
} catch {
completion(nil, .invalidJSON)
}
case 400: completion(nil, .badRequest)
case 404: completion(nil, .noRecordFound)
default:
print("**UNCAPTURED STATUS CODE FROM (getPatientDetailsPayout)\nSTATUS CODE: \(statusCode)")
completion(nil, .uncapturedStatusCode)
}
}
}
}
PatientPaymentDetailsViewController.swift
var patientProcedure: PatientProcedure! {
didSet {
performSegue(withIdentifier: cardCollectionCellIdentifier, sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == patientProcedureIndentifier {
if let userCardVC = segue.destination as? UserCardViewController {
userCardVC.patientProcedure = self.patientProcedure
}
}
//MARK: FUNCTION
func getPatientProcedureDetails(from: String) {
APIService.PatientList.getPatientProcedureDetails(chargedId: from) { (procedureDetails, error) in
guard let getProcedureDetails = procedureDetails, error == nil else {
SVProgressHUD.dismiss()
// return
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)
}
}
SVProgressHUD.dismiss()
return
}
self.patientProcedure = getProcedureDetails
print(getProcedureDetails)
SVProgressHUD.dismiss()
return
}
}
CollectionCell DidSelect函数
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
let row = indexPath.row
switch row {
case 0:
let cardController = UserCardViewController.init(nibName: "UserCardViewController", bundle: nil)
present(cardController, animated: true) {
let selectedPatientProcedureId = self.patientProcedure.id
self.getPatientProcedureDetails(from: selectedPatientProcedureId!)
self.performSegue(withIdentifier: patientProcedureIndentifier, sender: cell)
}
default: break
}
}
点击cell
时,它会指向我在问题中提到的fatal error
。并且突出显示了这一部分。希望您能帮到我,因为我试图在SO上阅读一些资料,但是不幸的是,我找到了可以解决我问题的解决方案。谢谢。
let selectedPatientProcedureId = self.patientProcedure.id