从API提取数据时,如何解决有关“致命错误:在展开可选值时意外发现nil”的问题?

时间:2019-06-04 05:27:45

标签: swift api alamofire uicollectionviewcell

我有一个应用,其中需要使用APIalamofire 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

0 个答案:

没有答案