はじめに
初めまして、株式会社やどかり超絶怒涛のOkaです。
入社してちょうど半年が経ちました。
希望していたスマホアプリ開発に携われて、
コードの理解に苦しみながらも日々楽しんで仕事しています。
今回のGOAL
みなさん、ご存知の通り12/13は全世界注目のマドリードダービーでしたね!
もちろん、僕が愛するAtletico de Madridの圧勝です!サッカー関係のAPIを使ってみました!(0-2で敗北...)
ということで、Atleticoの勝利を祝して
GOALは、"選手検索でAPI叩いて選手の詳細情報と画像を表示させる"です。
(成果物は一番下なのでskipしてもOkです!)
かっちょええ〜
前提
Xcode: 13.0
Podライブラリ: SwiftyJSON, AlamofireImage
GOALまでの大雑把な道筋
①APIを探す、使い方調査
②Xcodeでレイアウト作成
③APIを叩いてレスポンス取得、画面に表示
①APIを探す、使い方調査
これが意外と時間かかりました。。。
なかなか適切なAPIないもんですね。
そんな中見つけたのがこちら、API-FOOOTBALLです。
ドキュメント見るとわかりますが、このAPIで世界中のサッカー情報を網羅できちゃいます!!
試合のライブ情報、各選手のシュート数やデュエル勝利数などなど、ファンには堪らんデータがてんこ盛り!まじで!ほんま!やばい!!歓喜!万歳!
てことで、とりあえずFreeプラン(100calls/day)でサブスク登録。
ちなみに僕はRakuten Rapid API経由で登録しました。
Rakuten Rapid APIでは登録したAPIの利用状況をダッシュボードで一括管理できるのでおすすめです。
今回は選手の詳細情報を引っ張ってきたいので、
下記でどんなデータ構成で返却されるのかcheck!
ふむふむ、API叩いてギャンしてバァンしたら表示できそうや!!!
②Xcodeでレイアウト作成
レイアウトは今回のメインではないので超絶怒涛に割愛します。
ということで下記を作成しました。
上半分で条件指定して検索、下半分で検索結果を表示する構成です。
(シーズン、リーグ名、選手名で検索)
stackviewの中にポンポン部品を入れて行って、配置してあげただけです。
配置した部品を所有するクラスにアウトレットで紐付けます。
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します。
import UIKit
import SwiftyJSON //JSONデータを簡単に扱えるライブラリ
import AlamofireImage //URLから画像を取得するライブラリ
import Foundation
次にAPIを叩く処理を書きます。
今回はSearchボタンを押したら、パラメータを渡してリクエストする実装なので、Searchボタンを@IBActionで紐付けます。
これでタップされたイベントを検知して処理を走らせてくれます。
@IBAction func search(_ sender: Any) {
// ボタン押下時にしたい処理
}
そしてその中で、URLSessionを使用してAPI通信をし
@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!
コードの改良の余地はかなりありますが、
ここでビルドしてみます!
お〜、拾えてる拾えてる!!ひとまず安心。
次回はこのAPIでもうちょいええ感じなもん作ってみます〜
では、Hasta luego!