2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

複数apiを叩いて全ての結果が0件だった場合のみ処理をするお話

Posted at

0件の場合の表示処理について、GCD調べたんでそのまとめをしました

1.やりたいこと

複数のAPIの結果が0件だった場合に特定のviewを表示させたい
「複数の」って言うのが今回の大きなポイント。

image.png

2.何が難しいんでっか?

通常APIが一つの場合こんな感じでできる。

repository.apiHogeHoge1() { (result) in
            switch result {
           case .success(let response):
          
          if response.count == 0 {
            //apiが1つならここでできる
          }
}

しかし2つの場合こうなる

repository.apiHogeHoge1() { (result) in
            switch result {
           case .success(let response):
           
          if response.count == 0 {
            // ここに入った場合では条件不足
          }
}

repository.apiHogeHoge2() { (result) in
            switch result {
           case .success(let response):
          
          if response.count == 0 {
        // ここに入った場合では条件不足
          }
}
// 言わずもがなだがここでは判定できない......

まぁつまり
apiHogeHoge1()もapiHogeHoge2()も終了したら判定したいよね!!!
ってこと
非同期処理ってやつですね。

3.そこでGCDです

よく DispatchQueue.main.async って記述を見ると思います(僕だけかも...)
UI更新をしたいときはメインスレッドである必要があるので、このような記述を使いますね。

    DispatchQueue.main.async {
        // UI更新とか
    }

今回の場合だと
apiHogeHoge1()もapiHogeHoge2()も終了したら判定したいよね!!!
ってことで、キューのなかにタスクを入れて、全てのタスクがなくなったら実行するって形でやります。

こんな感じ。

        let dispatchGroup = DispatchGroup()
        //並列処理のキューを作成
        //labelに意味があるかは不明
        let dispatchQueue = DispatchQueue(label: "queue", attributes: .concurrent)



        dispatchQueue.async(group: dispatchGroup) {
            //キューに追加
            dispatchGroup.enter()
          repository.apiHogeHoge1() { (result) in
                      switch result {
                     case .success(let response):
                     
                     //結果入れとく
                     self.apiHogeHoge1Result = response
               //データが取得できたタイミングでキューから削除
               dispatchGroup.leave()
          }
        }

        dispatchQueue.async(group: dispatchGroup) {
            //キューに追加
            dispatchGroup.enter()
          repository.apiHogeHoge2() { (result) in
                      switch result {
                     case .success(let response):
                     
                     //結果入れとく
                     self.apiHogeHoge2Result = response
               //データが取得できたタイミングでキューから削除
               dispatchGroup.leave()
          }
        }
       }

       dispatchGroup.notify(queue: .main) {
       
              if self.apiHogeHoge1Result.count == 0 && self.apiHogeHoge2Result.count == 0 {
                  //どっちも0件なら0件用のviewを追加する
                  self.scrollview.addSubview(self.noEventView)
              }
       }

4.まとめ

キューがわかってれば、すんなり受け入れられるはず。
非同期処理はアプリ開発で欠かせないところなので使える違和感なく使える状態が望ましい。
これ以外にも「何を?」「どのタイミングで?」「実行する?」っていつも考えてる気がする

参考サイト

[Swift 3] Swift 3時代のGCDの基本的な使い方https://dev.classmethod.jp/smartphone/iphone/swift-3-how-to-use-gcd-api-1/
Swift 3における非同期処理
https://1000ch.net/posts/2016/dispatch-queue.html
非同期通信で、ある処理のあとに別の非同期通信を行いたい。
https://teratail.com/questions/72250
Concurrent Programming With GCD in Swift 3
https://developer.apple.com/videos/play/wwdc2016/720/

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?