Search code examples
iosswiftconcurrencygrand-central-dispatch

How to apply Async/await (like javascript) in iOS Swift?


I have a following code structure, how can I run this code on background thread and execute all the methods serially in FIFO.

How to wait for function to executes all its statements and then move to next function?


func downloadImagesAndProcess(){
// i need these methods to execute one by one i.e when saveimages completes fully only then call resizeimages
saveImages()
resizeImages()
shareImgs()

}

func saveImages(){

// long async tasks

for (index, image) in (self.images.enumerated())! {
              
     KingfisherManager.shared.retrieveImage(with: URL(string:image.imageFile)!) { result in
                    
                    switch result {
                    case .success(let value):
                    self.saveImageDocumentDirectory(image: value.image, imageName: imgNameStr)

                    case .failure(let error):
                        print(error) // The error happens
                    }
                  
                }
              
            }

}

func resizeImages(){

// long running tasks

}

func shareimgs(){

//share
}

I need these methods to execute one by one i.e. when saveImages completes fully only then call resizeImages

How to wait for function to executes all its statements and then move to next function?


Solution

  • The easiest thing to do is call the next method inside the completion of the previous one

    func saveImages(){
    
        let group = DispatchGroup()
        for (index, image) in (self.images.enumerated())! {
            group.enter()
            KingfisherManager.shared.retrieveImage(with: URL(string:image.imageFile)!) { result in
                switch result {
                case .success(let value):
                    self.saveImageDocumentDirectory(image: value.image, imageName: imgNameStr)
                case .failure(let error):
                    print(error) // The error happens
                }
                group.leave()
            }
        }
        group.notify(queue: .main) {
            // do your stuff, check if every image has been downloaded
            self.resizeImages() // this will be called after the completion of the current task
        }
    }
    

    Then in the resizeImages I guess there's another completion handler, inside that you'll call shareImgs