読者です 読者をやめる 読者になる 読者になる

hachinoBlog

hachinobuのエンジニアライフ

SwiftTaskであるAPI処理の結果をもとにSuccessでTask.allを使う方法

背景

ある通信処理の成功結果をもとに複数通信をネストせずに書きたかった SwiftTaskを使うと簡単にできる

コード


private func generateTaskA() -> Task<Float, [String], NSError?> {

  return Task { (fulfill, reject) in
    //通信処理 成功時にはStringの配列が得られる
    fulfill(results)          
  }

}

private func generateTaskB(successA: String) -> Task<Float, Int, NSError?> {

  return Task<Float, DestinationPlaceProtocol, NSError?> { progress, fulfill, reject, configure in
      //通信処理 成功時にはInt型の値が得られる
      fulfill(result)
  }

}

func fetchData() {
  
  generateTaskA().success { [unowned self] results -> Task<(completedCount: Int, totalCount: Int), [Int], NSError?> in
    //TaskAの成功時 results(Stringの配列)をもとにTaskBを複数作成
    let taskListB = results.map(self.generateTaskB)
    return Task.all(taskListB)
  }.success { numberResults in
    //TaskBの配列のTaskが全て成功した場合にくる
   //TaskBの成功オブジェクトの配列なのでnumberResultsは[Int]
  }

}

1つ目のsuccessの返り値であるTaskはTaskBの配列の結果として何が得られるかを指定する(successの中で処理するTaskの結果)

Task.allの場合は

public class func all(tasks: [Task]) -> Task<BulkProgress, [Value], Error>

返り値が上記のようになるので合わせる (BulkProgressは(completedCount: Int, totalCount: Int)のエイリアス