У меня есть ошибка, из-за которой я не понимаю, почему.
Моя проблема в том, что у меня есть три функции, имена которых - sendCourse, sendRequire, sendStep.
Первая функция sendCourse проста.Эта функция представляет собой простой сетевой запрос.
Функции sendRequire и sendStep аналогичны.Они содержат цикл for, который перебирает массив для отправки каждого элемента массива на сервер.В этой функции необходимо дождаться завершения предыдущего сетевого запроса (чтобы элемент был отправлен на сервер), чтобы отправить следующий элемент массива.
Наконец, у меня есть еще один метод, называемый sendRecipe.Этот метод выполняет sendCourse, sendRequire, sendStep.senRecipe должен ждать завершения sendCourse.Когда sendCourse завершен, функция sendRecipe должна выполнить sendRequire.Затем sendRecipe должен дождаться завершения sendRequire для выполнения sendStep.
Наконец, у меня есть кнопка, которая вызывает sendRecipe.
Когда я нажимаю на кнопку, мое приложение вылетает.
Вот мой код:
private func sendCourse(success: @escaping(() -> Void), errorHandling: @escaping((String) -> Void)) {
let dataCourse:[String:String] = [
"name":self.course.name,
"course_type_id":String(self.course.type.id),
"country_code":self.course.country.countryCode,
"dishes_number":String(self.course.dishesNumber),
"description":self.course.description
]
APIManager.sharedInstance.put(action: .courses, data: dataCourse, onSuccess: {(responseCode, data) -> Void in
if responseCode == 201 {
let jsonDecoder = JSONDecoder()
if let course = try? jsonDecoder.decode(Courses.self, from: data) {
self.course = course
success()
} else {
errorHandling("service unavailable")
}
} else {
errorHandling("service unavailable")
}
}, onFailure: {(error) -> Void in
errorHandling(error.localizedDescription)
})
}
private func sendRequire(success: @escaping(() -> Void), errorHandling: @escaping((String) -> Void)) {
let requireGroup = DispatchGroup()
var fail = false
for require in requires {
if fail == true {
break
}
requireGroup.enter()
let dataRequire:[String:String] = [
"course_id":String(self.course.id!),
"ingredient_id":String(require.ingredient.id),
"quantity":String(format: "%f", require.quantity)
]
APIManager.sharedInstance.put(action: .requires, data: dataRequire, onSuccess: {(responseCode, data) -> Void in
if responseCode == 201 {
requireGroup.leave()
success()
} else {
requireGroup.leave()
fail = true
errorHandling("Service unavailable")
}
}, onFailure: {(error) -> Void in
requireGroup.leave()
fail = true
errorHandling(error.localizedDescription)})
}
requireGroup.wait()
}
private func sendStep(success: @escaping(() -> Void), errorHandling: @escaping((String) -> Void)) {
let stepGroup = DispatchGroup()
var fail = false
for (index, step) in self.steps.enumerated() {
if fail == true {
break
}
stepGroup.enter()
var previousStepId=0
if index == 0 {
previousStepId = 0
} else {
previousStepId = steps[index-1].id!
}
let dataStep:[String:String] = [
"course_id":String(self.course.id!),
"description":step.description,
"duration_hours":String(step.durationHours),
"duration_minutes":String(step.durationMinutes),
"duration_seconds":String(step.durationSeconds),
"previous_step_id":String(previousStepId)
]
APIManager.sharedInstance.put(action: .steps, data: dataStep, onSuccess: {(responseCode, data) -> Void in
if responseCode == 201 {
let jsonDecoder = JSONDecoder()
if let step = try? jsonDecoder.decode(Step.self, from: data) {
self.steps[index] = step
stepGroup.leave()
success()
} else {
fail = true
errorHandling("service unavailable")
stepGroup.leave()
}
} else {
fail = true
errorHandling("service unavailable")
stepGroup.leave()
}
}, onFailure: {(error) -> Void in
errorHandling(error.localizedDescription)
fail = true
stepGroup.leave()
})
stepGroup.wait()
}
}
func sendRecipe(errorHandling: @escaping((String) -> Void)) {
DispatchQueue.global(qos: .background).sync {
self.sendCourse(success: {}, errorHandling: errorHandling)
}
DispatchQueue.global(qos: .background).sync {
self.sendRequire(success: {}, errorHandling: errorHandling)
}
DispatchQueue.global(qos: .background).sync {
self.sendStep(success: {}, errorHandling: errorHandling)
}
}
here is the code of the button:
@IBAction func doneBarButtonItemTapped(_ sender: UIBarButtonItem) {
recipe?.steps = steps
recipe?.sendRecipe(errorHandling: {(error) -> Void in
DispatchQueue.main.async {
let alert = UIAlertController(title: "Error", message: error, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "dismiss", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
})
}
вот захват моего экрана при падении приложения: захват XCode при падении приложения Спасибо за продвинутый