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

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

我有以下代码结构,如何在后台线程上运行此代码,并在FIFO中依次执行所有方法。

如何等待函数执行所有语句然后移至下一个函数?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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

如何等待函数执行所有语句然后移至下一个函数?


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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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: $0)
            }

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

        self.resizeImages()
    }
}

最简单的方法是在上一个方法的完成内调用下一个方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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