Post

Replies

Boosts

Views

Activity

Reply to How do I wait for a task to finish before proceeding with the program flow?
Hi, Completion handler did work for me in a different case, but here I am facing the same issue again and completion handler is not giving the expected result. Since I am new to Swift I am not sure if I have implemented it correctly. Here I am trying to download images based on a list of names from Firestore, and then adding them to a resource group. I am expecting when the statement trackedImages = trackedImages.union(self.newReferenceImages) executes, newReferenceImages should have the downloaded images. But it gets executed before the downloading is completed. Please help. func downloadArResources(listOfImages imageList: [String] ){         if !imageList.isEmpty {             for imageName in imageList {                 print("Image working on: \(imageName)")                 downloadAndAddToSet(name: imageName){                     if var trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main){                         trackedImages = trackedImages.union(self.newReferenceImages)                         print("new Bundle images = \(trackedImages.description)")                                              }                 }             }         }     }               func downloadAndAddToSet(name imageName: String, completion: @escaping () -> Void){         let FIRImageName = self.root.child("MagicFrame/\(self.userName)/images/\(imageName).jpg")         FIRImageName.getData(maxSize: 5 * 1024 * 1024) { data, error in             if let error = error {                 print("Error in downloading image: \(error)")             } else {                 if let image = UIImage(data: data!){                     if let cgimage = image.cgImage {                         let newImage = ARReferenceImage(cgimage, orientation: .up, physicalWidth: 0.2)                         newImage.name = imageName                         self.newReferenceImages.insert(newImage)                     }                 }             }         }         completion()     }
Jun ’22
Reply to How do I wait for a task to finish before proceeding with the program flow?
Thanks @blueturtle I have a much better understanding of how the completionHandler works. I have tried implementing it accordingly and it did work, but I am still facing the same problem when I use it in calls between classes. func refreshResources(forUser username: String, ARresourceReference imagesPresent: Set<ARReferenceImage>, completion: @escaping (Set<ARReferenceImage>) -> Void) {         self.userName = username         self.newReferenceImages = imagesPresent         getListandDownload()         DispatchQueue.main.async() { completion(self.newReferenceImages) } } Here getListandDownload() is a function of class CheckForDownloads that will perform some logic, download images and add them to newReferenceImages. Although all this takes some time (depends on network speed) it is working fine with the use of completionHandler. getListandDownload() is being called from a different class ARViewController's viewWillAppear method override func viewWillAppear(_ animated: Bool) {     super.viewWillAppear(animated) let configuration = ARImageTrackingConfiguration()            guard let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main) else{                 print("Problem in initializing AR Resources bundle")                 return             }    self.checkForDownloads.refreshResources(forUser: self.username, ARresourceReference: trackedImages) { imageSet in                  configuration.trackingImages = imageSet                  configuration.maximumNumberOfTrackedImages = 1                 // Run the view's session                 self.sceneView.session.run(configuration)             } } Here I am expecting that only after getListandDownload() is completed, the completion(self.newReferenceImages) should be called that will set the configurations and run the session. But what is happening now is that the completionHandler runs way sooner and debug log shows that the downloading is happening afterwards. I also tried using DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {     completion(self.newReferenceImages) } But it fails if the downloading takes more than 5 seconds, not what I am looking for.
Jun ’22