iOSアプリでapi叩いてみた

# はじめに
前回の記事で、golangでapiを作成しました。
→ [golangで楽々API作成](https://qiita.com/seaka829/items/b74a88ab4f3b83794910)
api作ったら、叩きたくなるのが男の性

今回の記事では、*簡単に*apiからjsonを取得し、table viewに表示する方法を書きたいと思います。
細かいところの説明は省略しますが、機会があったらまとめたいと思います。

#GitHubからEC2にPull
省略しますが、前回作成したapiを公開しました。

# 画面を作成する
とりあえず画面を作成します。
<img width="1680" alt="スクリーンショット 2019-12-11 0.02.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/3c6f2aed-64ee-34be-2d3e-536060a36d55.png">
Table Viewの上に、cellを置き、さらにその上にボタンやラベルを置きます。
今回は、「タスクの完了/未完了を設定するボタン」「タスク名を表示するラベル」「期限を表示するラベル」の3つを設置します。
コード上で識別できるように、3つそれぞれのtagに数字を設定します。
(画像では、完了/未完了を設定するボタンのtagに「1」を設定している)

# api叩いてみる
```ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url: URL = URL(string: "http://xxx.xxx.xxx.xxx:xxxx/api/v1/tasks")!
        let task: URLSessionTask  = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]
                let jsonMap = json.map { (jsonMap) -> [String: Any] in
                    return jsonMap as! [String: Any]
                }
                print(jsonMap)
            }
            catch {
                print(error)
            }
        })
        task.resume()
    }
}
```

viewDidLoad()は、画面描画の前に呼ばれるメソッド。
ここで、apiを叩いてみる！
task.resume()実行後、`data`の中にgetに対するレスポンスがかえってくる。
その後の処理で、JSONにパース。
実行結果↓（JSON形式でデータを取得できているのが確認できます。）
<img width="1680" alt="スクリーンショット 2019-12-11 1.00.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/ca86c3e8-a02c-3af2-1f12-31abd49fc919.png">


# TableViewのCellに表示してみる
```ViewController.swift
import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
    
    @IBOutlet weak var tableView: UITableView!
    
    var jsonMap: [[String: Any]] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
        let url: URL = URL(string: "http://xxx.xxx.xxx.xxx:xxxx/api/v1/tasks")!
        let task: URLSessionTask  = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]
                self.jsonMap = json.map { (jsonMap) -> [String: Any] in
                    return jsonMap as! [String: Any]
                }
                print(self.jsonMap)
            }
            catch {
                // 例外処理を書く
                print(error)
            }
        })
        task.resume()
    }
    
    // セルの設定
    // ここで、セルの中身を設定する
    func tableView(_ table: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = table.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let taskNameLbl = cell.viewWithTag(2) as! UILabel
        let deadlineLbl = cell.viewWithTag(3) as! UILabel
        
        taskNameLbl.text = jsonMap[indexPath.row]["TaskName"] as? String
        deadlineLbl.text = jsonMap[indexPath.row]["Deadline"] as? String
        
        return cell
    }
    
    // セル数の設定
    // 今回は、apiを叩いた後、jsonMapにデータが格納されるので、`jsonMap.count`を設定
    func tableView(_ table: UITableView, numberOfRowsInSection section: Int) -> Int {
        return jsonMap.count
    }
    
    // セルの高さを設定
    func tableView(_ table: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 90.0
    }
}
```
Main.storyboardのTable ViewをIBOutletで`tableView `と紐付けます。
その後、UITableViewDataSource, UITableViewDelegateを継承し、必要なメソッドを追加します。
cellの中身は、追加したメソッドの中で設定！

# 動かしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/8eb88ac5-ff7a-f1ed-84dd-4ce19338a2e4.png)
リストが表示されない...
デバックコンソールを見る限り、apiからデータの取得はできている...

# 原因
apiからのレスポンスがかえってくる前に、tableviewが描画されていることが原因！
レスポンス取得後、viewを再描画してあげればいい
`self.tableView.reloadData()`を`print(self.jsonMap)`の前後に追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/dd52e606-ac07-bae0-cce5-4486202e85a6.png)
無事表示できました。

# 今後
今回は、swiftでGETでapiからデータ取得を行いました。
データの取得以外にも更新/削除などアプリから操作できるようになりたいですね。
また、機能を拡張するにあたり、もう少し綺麗にコードを整理したいとおもいます。