【Swift】APIでサッカー選手検索してみた①

## はじめに

初めまして、株式会社やどかり超絶怒涛のOkaです。
入社してちょうど半年が経ちました。
希望していたスマホアプリ開発に携われて、
コードの理解に苦しみながらも日々楽しんで仕事しています。

## 今回のGOAL

みなさん、ご存知の通り12/13は全世界注目のマドリードダービーでしたね！
~~もちろん、僕が愛するAtletico de Madridの圧勝です！
ということで、Atleticoの勝利を祝して~~サッカー関係のAPIを使ってみました！(0-2で敗北...)
GOALは、"選手検索でAPI叩いて選手の詳細情報と画像を表示させる"です。
(成果物は一番下なのでskipしてもOkです！)
![IMG_6270.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318159/cc31cbeb-2848-af41-3d4b-bf58feff9610.jpeg)
かっちょええ〜

## 前提
Xcode: 13.0
Podライブラリ： SwiftyJSON, AlamofireImage

## GOALまでの大雑把な道筋

①APIを探す、使い方調査
②Xcodeでレイアウト作成
③APIを叩いてレスポンス取得、画面に表示

## ①APIを探す、使い方調査

これが意外と時間かかりました。。。
なかなか適切なAPIないもんですね。

そんな中見つけたのがこちら、[API-FOOOTBALL](https://www.api-football.com/)です。
ドキュメント見るとわかりますが、このAPIで世界中のサッカー情報を網羅できちゃいます！！
試合のライブ情報、各選手のシュート数やデュエル勝利数などなど、ファンには堪らんデータがてんこ盛り！まじで！ほんま！やばい！！歓喜！万歳！

てことで、とりあえずFreeプラン(100calls/day)でサブスク登録。
ちなみに僕は[Rakuten Rapid API](https://api.rakuten.co.jp/ja/)経由で登録しました。
Rakuten Rapid APIでは登録したAPIの利用状況をダッシュボードで一括管理できるのでおすすめです。

今回は選手の詳細情報を引っ張ってきたいので、
下記でどんなデータ構成で返却されるのかcheck!
ふむふむ、API叩いてギャンしてバァンしたら表示できそうや！！！

![スクリーンショット 2021-12-13 1.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318159/5875dd76-b0b2-04db-be4f-bf0f2e1fb3fc.png)

## ②Xcodeでレイアウト作成

レイアウトは今回のメインではないので超絶怒涛に割愛します。
ということで下記を作成しました。
上半分で条件指定して検索、下半分で検索結果を表示する構成です。
(シーズン、リーグ名、選手名で検索)
stackviewの中にポンポン部品を入れて行って、配置してあげただけです。
![スクリーンショット 2021-12-13 1.34.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318159/c3f21e8b-b144-5fa0-d1cd-68b6f19a4383.png)

配置した部品を所有するクラスにアウトレットで紐付けます。

```Swift:ViewController.swift
class ViewController: UIViewController {
    @IBOutlet weak var seasonTextField: UITextField!
    @IBOutlet weak var leagueTextField: UITextField!
    @IBOutlet weak var playerNameTextField: UITextField!
    @IBOutlet weak var playerName: UILabel!
    @IBOutlet weak var teamLabel: UILabel!
    @IBOutlet weak var ageLabel: UILabel!
    @IBOutlet weak var nationalityLabel: UILabel!
    @IBOutlet weak var playerImage: UIImageView!

// TextFiledに入力された値を格納する変数を用意
    var seasonText = ""
    var leagueText = ""
    var playerNameText = ""
}
```

## ③APIを叩いてレスポンス取得、画面に表示

さあ、いよいよ山場ですね。
まずは、podライブラリをimportします。

```Swift:ViewController.swift
import UIKit
import SwiftyJSON //JSONデータを簡単に扱えるライブラリ
import AlamofireImage //URLから画像を取得するライブラリ
import Foundation
```

次にAPIを叩く処理を書きます。
今回はSearchボタンを押したら、パラメータを渡してリクエストする実装なので、Searchボタンを@IBActionで紐付けます。
これでタップされたイベントを検知して処理を走らせてくれます。

```Swift:ViewController.swift
@IBAction func search(_ sender: Any) {
// ボタン押下時にしたい処理
}
```

そしてその中で、URLSessionを使用してAPI通信をし

```Swift:ViewController.swift
    @IBAction func search(_ sender: Any) {
// TextFieldに入力された3項目を定義していた変数に格納
        seasonText = seasonTextField.text ?? ""
        leagueText = leagueTextField.text ?? ""
// リーグはidをパラメータとして渡すため、リーグの名前に応じてswitch文で分岐 APIのドキュメントでid確認必要
        switch leagueText {
        case "Liga":
            leagueText = "140"
        case "League1":
            leagueText = "61"
        case "Premier":
            leagueText = "39"
        case "SerieA":
            leagueText = "135"
        case "Eredivisie":
            leagueText = "88"
        default:
            abort()
        }
        playerNameText = playerNameTextField.text ?? ""

// URLSessionを使用してAPI通信

// ヘッダ情報(RapidAPIで取得したhostとkey情報)を格納        
        let headers = [
            "x-rapidapi-host": "api-football-v1.p.rapidapi.com",
            "x-rapidapi-key": "71d5d7e247msh2e0b3ec472fd452p1b9c2fjsnacb7856b6d30"
        ]

// リクエストを生成
// urlに"leagueText","seasonText"と"playerNameText"を渡してあげてリクエストを送る
// .useProtocolCachePolicyでキャッシュがあればそれを使う
// 10秒でタイムアウト
        let request = NSMutableURLRequest(url: NSURL(string: "https://api-football-v1.p.rapidapi.com/v3/players?league=\(leagueText)&season=\(seasonText)&search=\(playerNameText)")! as URL,
                                                cachePolicy: .useProtocolCachePolicy,
                                            timeoutInterval: 10.0)
// リクエストのhttpメソッドをGETに設定
        request.httpMethod = "GET"
// リクエストのヘッダーに上記headersをセット
        request.allHTTPHeaderFields = headers
// URL経由でデータの通信を行うURLSessionのインスタンスを取得
//　.sharedはデフォルト値
        let session = URLSession.shared
// 個々のリクエストであるdataTaskメソッド
// URLRequest型のrequestと通信完了時のクロージャを渡してタスクを生成(コールバック関数と呼ばれ、通信完了後に取得データを用いて中の処理が実行される)
        let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
// 取得したdataをJSON形式に変換し、各データを取得
                if let json = try? JSON(data: data!) {
                    let name = json["response"][0]["player"]["name"]
                    let team = json["response"][0]["statistics"][0]["team"]["name"]
                    let age = json["response"][0]["player"]["age"]
                    let nationality = json["response"][0]["player"]["nationality"]
                    let imageURL = json["response"][0]["player"]["photo"]
                    let url = NSURL(string: imageURL.stringValue)
                    DispatchQueue.main.async() { () -> Void in
                        self.playerName.text = name.stringValue
                        self.teamLabel.text = team.stringValue
                        self.ageLabel.text = age.stringValue
                        self.nationalityLabel.text = nationality.stringValue
                        self.playerImage.af.setImage(withURL: url! as URL)
                    }
                }
        })
// タスクの実行
        dataTask.resume()
    }
```

## GOAL！

コードの改良の余地はかなりありますが、
ここでビルドしてみます！

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2318159/99fd55fa-2d04-b7fe-f29f-b3b2c4f950f9.gif)


お〜、拾えてる拾えてる！！ひとまず安心。
次回はこのAPIでもうちょいええ感じなもん作ってみます〜

では、Hasta luego!