如何在iOSSwift中应用Async/await(如javascript)?

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

我有下面的代码结构,我如何运行在后台线程上执行这段代码并在 FIFO 中串行执行所有方法。

如何等待函数执行完所有语句然后转到下一个函数?


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
}

我需要这些方法一个一个地执行,即当 saveImages 完全完成时才调用 resizeImages

如何等待函数执行完所有语句然后转到下一个函数?

最简单的方法就是在里面调用下一个方法完成上一个

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
    }
}

然后在 resizeImages 中,我猜还有另一个完成处理程序,在里面 你会调用 shareImgs

您可以将此框架用于 Swift 协程 - https://github.com/belozierov/SwiftCoroutine

当你调用 await 时,它不会阻塞线程,只会挂起协程,所以你也可以在主线程中使用它。

func saveImages() {
    DispatchQueue.main.startCoroutine {
        let manager = KingfisherManager.shared

        for (index, image) in (self.images.enumerated())! {
            let url = URL(string: image.imageFile)!

            let result = try Coroutine.await {
                manager.retrieveImage(with: url, completionHandler: [=10=])
            }

            switch result {
            case .success(let value):
                self.saveImageDocumentDirectory(image: value.image, imageName: imgNameStr)
            case .failure(let error):
                print(error)
            }
        }

        self.resizeImages()
    }
}