I have a single view application that uploads images to a remote server. When the user submits the upload, I use a second view controller that displays as a custom popup and shows the file upload progress. When the upload is complete, the custom popup unwinds to the first viewController. I am using the notification-obersever pattern to communicate between the two viewControllers.
My problem is the following: When I upload large files, the upload progress bar can be observed and the custom popup unwinds after the upload is complete. When I am uploading a small file, the upload time is very faast, even though the file is successfully uploaded, the upload progress is not observed and the custom popup does not unwind (see code below).
I'm not sure that I have set up the notification-observer pattern up correctly?
FIRST VIEWCONTROLLER:
Alamofire.upload(
multipartFormData: { multipartFormData in
for(key, value) in sendParamters{
multipartFormData.append((value.data(using: .utf8)!), withName: key)
}
for fileURL in arrayURLToUpload{
print("fileURL: \(fileURL)")
multipartFormData.append(fileURL, withName: "file[]")
}
},
to: UPLOAD_URL,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
/**TRACK PROGRESS OF UPLOAD**/
upload.uploadProgress { progress in
print("ECNTERFILENAME: \(progress.fractionCompleted)")
let progress = progress.fractionCompleted
// NOTIFICATION - UPLOAD PROGRESS
NotificationCenter.default.post(name: notifcationName, object: nil, userInfo: ["progress": progress])
}
/***/
// 'responseJSON' FIRES WHEN UPLOAD IS COMPLETE
// IT ALSO TO FIRES WHEN THE IS INTERNET CONNECTIVITY ISSUES
upload.responseJSON { response in
// NOTIFICATION UPLOAD COMPLETE
NotificationCenter.default.post(name: uploadFinishName, object: nil, userInfo: ["response": response])
}
case .failure(let encodingError):
print("UPLOAD ERROR")
print(encodingError)
}
}
)
SECOND VIEWCONTROLLER:
override func viewDidLoad() {
super.viewDidLoad()
self.createUploadObserver()
self.createUploadFinishObserver()
if txtLabelOutlet == nil{ // WHEN IMAGE('tickok') HAS REPLACED 'txtLabelOutlet'
reformTxtLabel()
}
self.infoLabelOutlet.textColor = UIColor.black // CAN BE RED WHEN NETWORK CONNECTION IS LOST
self.progressOutlet.progress = 0
}
func createUploadObserver(){
print("createUploadObserver ..")
NotificationCenter.default.addObserver(forName: notifcationName, object: nil, queue: OperationQueue.main) { (notification) in
guard
var arrayN = notification.userInfo as? [String:Double],
let num = arrayN["progress"] else{
print("no valid data")
return
}
// UPDATE PROGRESS BAR
let progress = Float.init(num)
self.progressOutlet.progress = progress
// UPDATE LABEL
let percent = Int(progress*100)
print("percent: \(percent)")
if let progressOut = self.txtLabelOutlet{
print("OUTLET EXISTS!")
progressOut.text = "\(percent)%"
}else{
print("OUTLET DOES NOT EXIST")
}
}
}
func createUploadFinishObserver(){
print("createUploadFinishObserver ..")
NotificationCenter.default.addObserver(forName: uploadFinishName, object: nil, queue: OperationQueue.main) { (notification) in
print("notification.userInfo: \(notification.userInfo)")
guard let response = notification.userInfo as? [String: DataResponse<Any>] else{
print("Error completion response")
return
}
guard
let respObj = response["response"] as? DataResponse<Any>,
let result = respObj.result as? Result<Any> else{return}
if let value = result.value{
print("value: \(value)")
}
if result.description == "SUCCESS"{
// UPLOAD COMPLETE
// SHOW VIDEO CAPTURE
print("upload success")
if let progressOut = self.txtLabelOutlet{
print("OUTLET EXISTS - REMOVE FROM SUPERVIEW")
progressOut.removeFromSuperview()
}else{
print("OUTLET DOES NOT EXIST to remove from superview")
}
// ADD GREEN TICK IMAGE TO SHOW UPLOAD SUCCESS PROGRAMTICALLY
let image = UIImage.init(named: "tickok")
self.showCompleteTickImage(image: image!, completion: {
// DELAY EXECUTION OF DIMISS POPUP BY 2 SECONDS
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print("DISMISS PROGRESS POPUP")
// DISMISS POUP AND SHOW IMAGE CAPTURE AGAIN
self.performSegue(withIdentifier: "inwindme2", sender: self)
}
})
}else{
// HANDLE UPLOAD FAIL
print("upload fail")
self.infoLabelOutlet.text = "Network Connection Lost"
self.infoLabelOutlet.textColor = UIColor.red
}
}
}
May be swap
self.createUploadFinishObserver()
self.createUploadObserver()
As it seems that the popupVC when uploading a small file hadn't been yet registered , so the finish post occurs before the observe , also you can start the upload in the completion of the present of that popup ,
self.present(popup,animated:true) {
// start upload
}
If segue
self.performSegue(/////
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// start upload
}
The notificationCenter to work , your app logic must be 100% sure that the post occurs after the observe