Reputation: 199
I want Alamofire to upload data to the server and depends on the result:
My code works fine on iOS 9 and 11, but on iOS 10 on success case only hides progress alert. Users are confused and submit the form again and again
Alamofire.upload(multipartFormData: { MultipartFormData in
MultipartFormData.append((self.model.name?.data(using: String.Encoding.utf8)!)!, withName: "Form[name]")
MultipartFormData.append((self.model.category?.description.data(using: String.Encoding.utf8)!)!, withName: "Form[category]")
if (self.filePreview.count>0) {
for (index,preview) in self.filePreview.enumerated() {
if preview != nil
let data = UIImageJPEGRepresentation((preview?.getImage())!, 80)
MultipartFormData.append(data!, withName: "Form[files]["+String(describing:index)+"]", fileName: "attachment"+String(describing: index)+".JPG", mimeType: preview!.getMime())
}
}
}
debugPrint(MultipartFormData)
}, to: url, encodingCompletion: { (result) in
switch result {
case .success( _, _, _):
progressAlert.dismiss(animated: true, completion: nil)
self.dismiss(animated: true, completion: nil)
let doneAlert = UIAlertController(title: "Success", message: "Your message was sent", preferredStyle: .alert)
let donedOk = UIAlertAction(title: "OK", style: .default, handler: nil)
doneAlert.addAction(donedOk)
self.present(doneAlert, animated: true, completion: nil)
break
case .failure( _):
progressAlert.dismiss(animated: true, completion: nil)
let doneAlert = UIAlertController(title: "Failed", message: "Your message was not sent", preferredStyle: .alert)
let donedOk = UIAlertAction(title: "OK", style: .default, handler: nil)
doneAlert.addAction(donedOk)
self.present(doneAlert, animated: true, completion: nil)
break
}
})
Upvotes: 1
Views: 184
Reputation: 156
The order should be.
Just to update code by rocky :
There´s no need to switch to MainQueue, Math Thompson on the resulting closure output to DispatchQueue.main.async.
So From my point of view interactions should be like :
switch result {
case .success( _, _, _):
//1
progressAlert.dismiss(animated: true, completion: nil)
//2
let doneAlertController = UIAlertController(title: "Success", message: "Your message was sent", preferredStyle: .alert)
let donedOk = UIAlertAction(title: "OK", style: .default) { (action) in
//3
self.dismiss(animated: true, completion: nil)
}
doneAlertController.addAction(donedOk)
self.present(doneAlertController, animated: true, completion: nil)
break
. . . . . .
Upvotes: 0
Reputation: 199
Working with completition handlers and using UIApplication.shared.keyWindow?.rootViewController
to find current top ViewController solved problem. Progress alert hides, current view controller dismisses, and success alert appears. Code:
progressAlert.dismiss(animated: true) {
let doneAlert = UIAlertController(title: "Отправлено", message: "Your message was sent", preferredStyle: .alert)
let donedOk = UIAlertAction(title: "Success", style: .default, handler: nil)
doneAlert.addAction(donedOk)
self.dismiss(animated: true) {
let presentingVC = UIApplication.shared.keyWindow?.rootViewController
presentingVC?.present(doneAlert, animated: true, completion: nil)
}
}
Upvotes: 1
Reputation: 3235
Issue with presenting a UIAlertController
on the Controller whose view is not in the window hierarchy, firstly you are dismissing the controller & presenting UIAlertController
on that dismissed controller.
You have to take a reference of controller on which the current controller is presenting, then after dismissing of current controller present UIAlertController
on that previous one.
Update user interface on Main dispatch queue.
DispatchQueue.main.async {
let controller = self.presentingViewController
self.dismiss(animated: true) {
let doneAlert = UIAlertController(title: "Success", message: "Your message was sent", preferredStyle: .alert)
let donedOk = UIAlertAction(title: "OK", style: .default, handler: nil)
doneAlert.addAction(donedOk)
controller?.present(doneAlert, animated: true, completion: nil)
}
}
Upvotes: 0