我正在检查我的应用,尝试登录后顺利登录我的帐户,然后突然崩溃了,并显示了致命错误:索引超出范围出现在代码的这一部分>
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()
}
}
答案 0 :(得分:0)
您始终可以在访问数组之前检查数组是否具有足够的元素。
if demographicsArray.count > 0 {
completion(demographicsArray[0], nil)
} else {
// handle empty array completion
}
注意:为什么数据库在处理数据之前先返回数据?
答案 1 :(得分:0)
我更喜欢使用“后卫”而不是“如果”
guard demographicsArray.count > 0 else {
completion(nil, .noDemographicsAtPosition)
}
completion(resonseToSend, nil)
我认为这种方式更具可读性。
建议:getPatientInformation承担很多责任,如果将其划分为其他函数,例如:
func getPatientInformationURL() -> String
func processResponse(completion: @escaping getPatientInformationTaskCompletion<Any>)
可能它使您的代码更具可读性,希望对您有所帮助。