簡體   English   中英

在數組為空時如何避免從API提取數據時應用崩潰

[英]How to avoid app crashing when pulling data from API when array is empty

我正在檢查我的應用程序,嘗試登錄后順利登錄了我的帳戶,然后突然崩潰了,並顯示了致命錯誤:這部分代碼中出現索引超出范圍

completion(demographicsArray[0], nil)

經過檢查,后端中的數據轉儲過程仍在進行中,這就是為什么我這一端的數組為空,而沒有數據被提取的原因。 如何防止應用程序崩潰以及如何添加警報消息,以通知用戶其記錄仍在處理中? 請幫助我解決一個星期的問題,但仍然無法解決。 以下代碼供您參考。 謝謝。

APIService.swift

 static func getPatientInformation(informationType: PatientInformationType, tokenType: String, token: String, hospitalNumber: String, completion: @escaping getPatientInformationTaskCompletion<Any>) {

        var patientInformationURL: URL!

        switch informationType {
            case .allergies:
                patientInformationURL = URL(string: "\(Endpoint.Patient.allergies)?hn=\(hospitalNumber)")
            case .demographics:
                patientInformationURL = URL(string: "\(Endpoint.Patient.demographics)?hn=\(hospitalNumber)")
            case .diagnosis:
                patientInformationURL = URL(string: "\(Endpoint.Patient.diagnosis)?hn=\(hospitalNumber)")
            case .medications:
                patientInformationURL = URL(string: "\(Endpoint.Patient.medications)?hn=\(hospitalNumber)")
        }

        guard patientInformationURL != nil else {
            completion(nil, .invalidURL)
            return
        }

        let header: HTTPHeaders = [
            "Authorization": "\(tokenType) \(token)",
            "Accept": "application/json"
        ]

        Alamofire.request(patientInformationURL, headers: header).responseJSON(completionHandler: { (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)

                    return
                }

                let decoder = JSONDecoder()

                switch (informationType) {
                case .allergies:
                    do {
                        let allergyArray = try decoder.decode([Allergies].self, from: jsonData)
                        completion(allergyArray, nil)
                    }catch {
                        completion(nil, .invalidJSON)
                    }
                case .demographics:
                    do {
                        let demographicsArray = try decoder.decode([Demographics].self, from: jsonData)
                            completion(demographicsArray.first, nil)
                        }catch {
                            completion(nil, .invalidJSON)
                    }

                case .diagnosis:
                    do {
                        let diagnosisArray = try decoder.decode([Diagnosis].self, from: jsonData)
                        completion(diagnosisArray, nil)
                    }catch {
                        completion(nil, .invalidJSON)
                    }
                case .medications:
                    do {
                        let medicationArray = try decoder.decode([Medication].self, from: jsonData)
                        completion(medicationArray, nil)
                    }catch {
                        completion(nil, .invalidJSON)
                    }
                }
            case 401:
                completion(nil, .unauthorizedToken)
            default:
                print("UNCAPTURED STATUS CODE FROM getPatientInformation\nSTATUS CODE: \(statusCode)")
                completion(nil, .uncapturedStatusCode)
            }
        })
    }

PatientProfileViewController.swift

func getPatientInfo() {
    guard let username = KeychainManager.getUsername(),
        let tokenType = KeychainManager.getTokenType(),
        let token = KeychainManager.getToken() else { return }

    SVProgressHUD.setDefaultMaskType(.black)
    SVProgressHUD.show(withStatus: "Retrieving Patient Information")

    APIService.Patients.getPatientInformation(informationType: .demographics,
                                              tokenType: tokenType, token: token,
                                              hospitalNumber: username) { (demographics, error) in

        guard let patientInformation = demographics as? Demographics, error == nil else {
            if let networkError = error {
                switch networkError {
                    case .noNetwork:
                        let popupDialog = PopupDialog(title: "No Network", message: "\(networkError.rawValue)")
                        popupDialog.addButton(DefaultButton(title: "OK", action: nil))
                        self.present(popupDialog, animated: true, completion: nil)
                    default:
                        let popupDialog = PopupDialog(title: "Error", message: "There is something went wrong. Please try again")
                        popupDialog.addButton(DefaultButton(title: "OK", action: nil))
                        self.present(popupDialog, animated: true, completion: nil)
                }
            }

            SVProgressHUD.dismiss()
            return
        }



        self.patientDemographics = patientInformation

        self.welcomeLabel.text = self.patientDemographics.displayName ?? "Welcome"

        self.patientInformationTableView.reloadData()
        SVProgressHUD.dismiss()
    }
}

您始終可以在訪問數組之前檢查數組是否包含足夠的元素。

if demographicsArray.count > 0 {
    completion(demographicsArray[0], nil)
} else {
    // handle empty array completion
}

注意:為什么數據庫在處理數據之前先返回數據?

我更喜歡使用“后衛”而不是“如果”

guard demographicsArray.count > 0 else {
  completion(nil, .noDemographicsAtPosition)
}

completion(resonseToSend, nil)

我認為這種方式更具可讀性。

忠告:getPatientInformation承擔很多責任,如果將其划分為其他函數,例如:

func getPatientInformationURL() -> String
func processResponse(completion: @escaping getPatientInformationTaskCompletion<Any>)

可能它使您的代碼更具可讀性,希望對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM