DispatchGroupの.leaveと.notifyを使用して取得したデータを表示（楽天API）

#今回の内容

* 最近、`DispatchQueue.main.asyncAfter`をよく使ってましたが、データの取得が終わった時に`UITableView`に表示させる為に`DispatchGroup`の`.leave`と`.notify`を使用してます。

#コード

##Model

```Swift:GetDataDetailModel
struct GetDataDetailModel{
    
    let mediumImageURL:String?
    let itemName:String?
    let itemPrice:Int?
    let itemCaption:String?
}

```
```Swift:AlamofireProcess
import Alamofire
import SwiftyJSON

class AlamofireProcess{

    public var getDataResultArray = [GetDataDetailModel]()
    private var keyword:String?
    
    init(getKey:String?){
        
        keyword = getKey
    }
}

extension AlamofireProcess{
    
    public func getItemDetailData(completion: @escaping() -> Void){
        
        guard let key = keyword else { return }
        
        let apiKey = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?format=json&keyword=\(key.urlEncoded)&applicationId=作成したアプリID"
        
        AF.request(apiKey, method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON {[self] response in
            
            switch response.result{
                
            case .success:
                
                let jsonDetail = JSON(response.data as Any)
                getDataResultArray = []
                
                for dataCount in 0..<jsonDetail["Items"].count{
                    
                    if let getMediumImageURL = jsonDetail["Items"][dataCount]["Item"]["mediumImageUrls"][0]["imageUrl"].string,
                       let getItemName = jsonDetail["Items"][dataCount]["Item"]["itemName"].string,
                       let getItemPrice = jsonDetail["Items"][dataCount]["Item"]["itemPrice"].int,
                       let getItemCaption = jsonDetail["Items"][dataCount]["Item"]["itemCaption"].string{
                        
                        getDataResultArray.append(GetDataDetailModel(mediumImageURL: getMediumImageURL,
                                                                     itemName: getItemName,
                                                                     itemPrice: getItemPrice,
                                                                     itemCaption: getItemCaption))
                    }
                    
                }
                completion()
               
            case .failure:
                
                completion()
            }
        }
    }
}

extension String{

    var urlEncoded:String{

        let charset = CharacterSet.alphanumerics.union(.init(charactersIn: "/?-._~"))
        let remove = removingPercentEncoding ?? self

        return remove.addingPercentEncoding(withAllowedCharacters: charset) ?? remove
    }
}
```

##View

###Main.storyboard

<img width="150" alt="69F900EB-C36B-4257-8460-45FC523CCFF6_4_5005_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/13885a55-3f6d-12ea-6933-926d90950f18.jpeg">

###SearchResultCell
 
<img width="250" alt="27768BE6-0468-4453-B3E9-2989E1B13DC5_4_5005_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/74feb718-ea10-5bae-7b08-a839964fbb60.jpeg"> 

```Swift:SearchResultCell
import UIKit

class SearchResultCell: UITableViewCell {

    @IBOutlet weak var mediumImageView: UIImageView!
    @IBOutlet weak var itemNameLabel: UILabel!
    @IBOutlet weak var itemPriceLabel: UILabel!
    @IBOutlet weak var itemCaptionView: UITextView!
    
    override func awakeFromNib() {
        super.awakeFromNib()
  
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        
        mediumImageView.image = UIImage(named: "")
        itemNameLabel.text = ""
        itemPriceLabel.text = ""
        itemCaptionView.text = ""
    }
}
```

##Controller

```Swift:
import UIKit
import SDWebImage

class ViewController: UIViewController {
  
    @IBOutlet weak var searchTextField: UITextField!
    @IBOutlet weak var searchButton: UIButton!
    @IBOutlet weak var resultTableView: UITableView!
    
    private let alamofireProcess = AlamofireProcess(getKey: nil)
    
    private let dispatchGroup = DispatchGroup()
    private let dispachQueue = DispatchQueue(label: "alamofire",attributes: .concurrent)
    
    private var cellContentsArray = [GetDataDetailModel]()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        resultTableView.register(UINib(nibName: "SearchResultCell", bundle: nil), forCellReuseIdentifier: "ItemDetailCell")
        resultTableView.delegate = self
        resultTableView.dataSource = self
    
    }

    @IBAction func search(_ sender: UIButton) {
        
        let afProcess = AlamofireProcess(getKey: searchTextField.text)
        
        dispatchGroup.enter()
        dispachQueue.async {[self] in
            
            afProcess.getItemDetailData {
                
                self.dispatchGroup.leave()
            }
        }
        
        dispatchGroup.notify(queue: .main){ [self] in
            
            cellContentsArray = afProcess.getDataResultArray
            print(cellContentsArray)
            resultTableView.reloadData()
        }
    }
    
}

extension ViewController:UITableViewDelegate{
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        
        return tableView.frame.height / 2.4
    }
}


extension ViewController:UITableViewDataSource{
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return cellContentsArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "ItemDetailCell", for: indexPath) as! SearchResultCell
        
        cell.mediumImageView.sd_setImage(with: URL(string: cellContentsArray[indexPath.row].mediumImageURL!), completed: nil)
        cell.itemNameLabel.text = cellContentsArray[indexPath.row].itemName
        cell.itemPriceLabel.text = String(cellContentsArray[indexPath.row].itemPrice!) + "円"
        cell.itemCaptionView.text = cellContentsArray[indexPath.row].itemCaption
        
        return cell
    }
}
```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。