WEBサイト制作・アプリ開発・システム開発・ブランディングデザイン制作に関するご相談はお気軽にご連絡ください。
構想段階からじっくりとヒアリングし、お客様の課題にあわせたアプローチ手法でお客様の“欲しかった”をカタチにしてご提案いたします。
Blog スタッフブログ
Swift
システム開発
[Swift]DispatchGroupでAPIコールを並列実行
こんにちは、株式会社MIXシステム開発担当のBloomです。
早速本題のDispatchGroupでAPIコールを並列実行する手順について、
お仕事の中で得た知見を共有させていただきたいと思います。
DispatchGroupとは
DispatchGroup – Apple Developer Documentation
DispatchGroupは複数の非同期タスクの実行を集約し、そのグループの動作を同期させることのできる標準クラスです。
実際に動作を見てみましょう。
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.global().async {
let dispatchGroup = DispatchGroup()
var apiResult1: Int = 0
var apiResult2: Int = 0
var apiResult3: Int = 0
dispatchGroup.enter()
self.api1 { response in
apiResult1 = response
dispatchGroup.leave()
}
dispatchGroup.enter()
self.api2 { response in
apiResult2 = response
dispatchGroup.leave()
}
dispatchGroup.enter()
self.api3 { response in
apiResult3 = response
dispatchGroup.leave()
}
dispatchGroup.notify(queue: .main) {
// ここはメインスレッドです
print("results: \(apiResult1), \(apiResult2), \(apiResult3)")
}
}
}
func api1(handler:@escaping (Int) -> Void) {
DispatchQueue.global().async {
print("api1 start!")
sleep(1)
print("api1 finished!")
handler(1)
}
}
func api2(handler:@escaping (Int) -> Void) {
DispatchQueue.global().async {
print("api2 start!")
sleep(2)
print("api2 finished!")
handler(2)
}
}
func api3(handler:@escaping (Int) -> Void) {
DispatchQueue.global().async {
print("api3 start!")
sleep(3)
print("api3 finished!")
handler(3)
}
}
}
実行結果ログ
api3 start!
api2 start!
api1 start!
api1 finished!
api2 finished!
api3 finished!
results: 1, 2, 3
時間差で完了するAPIコールの結果を簡単にまとめられました。
このコードではdispatchGroup.enter() をAPIコールのたびに実行する必要があり、
同様にAPIの処理が終了したらdispatchQueue.leave()を必ず実行する必要があります。
そのため、API側でタイムアウト等が発生した場合に必ずキャッチしハンドラまで処理を通達させる必要があるため注意してください。
これでAPIを並列して実行することができるようになりました。良かったですね。