【Swift】Splatoon2のAPIを使用して、戦績を取得してみる

#概要
Splatoon2のAPIを使用しCodableで戦績を取得する方法についてまとめました。


使用するAPI
https://app.splatoon2.nintendo.net/api/results
最新の５０戦分の戦績を取得できます。

＊注意点
APIを使用するためには、cookieとしてiksm_sessionが必要になります。
イカリング２の通信内容からiksm_sessionを確認できるため、Fiddler等を使用して自分のiksm_sessionを確認する必要があります。


#API通信で戦績を取得する
cookieにiksm_sessionをセットする。

```
let url: URL = URL(string: "https://app.splatoon2.nintendo.net/api/results")!

let cookieHeader = ["Set-Cookie": "iksm_session=1234..."]
let cookie = HTTPCookie.cookies(withResponseHeaderFields: cookieHeader, for: url)
HTTPCookieStorage.shared.setCookies(cookie, for: url, mainDocumentURL: url)
```


URLSessionDataTaskを使いAPIから戦績を取得します。

```
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in})
//タスク開始
task.resume()
```

５０戦分の戦績がJSON形式で返ってきますが、色々情報があるためキーごとに分解して取得する必要があります。


#JSONのデータ内容
返ってくるJSONのデータ内容を簡易的にまとめました。
この他にも、自分のギアの情報も取得できます。
取得出来るのは自分の戦績のみで、他のプレイヤーの情報の取得には別のAPIを使用する必要があります。

```
{
　　　"results": [
　　　{
　　　　　　"battle_number": 1234
　　　　　　"rule": {
　　　　　　　　　"name": ルール
     　　　}
　　　　　　"stage": {
　　　　　　　　　"name": ステージ
　　　　　　}
　　　　　　"udemae": {　         //ガチマッチのみ
　　　　　　　　　"name": ウデマエ　//ガチマッチのみ
　　　　　　}
　　　　　　"my_team_result":{
　　　　　　　　　"name": 試合結果
　　　　　　}
　　　　　　"x_power": Xパワー　//ガチマッチのみ
　　　　　　"player_result":{
　　　　　　　　　"assist_count": アシストキル数
　　　　　　　　　"death_count": デス数
　　　　　　　　　"kill_count": キル数
　　　　　　　　　"special_count": スペシャルカウント数
　　　　　　　　　"player": {
　　　　　　　　　　　　"nickname: ユーザ名
　　　　　　　　　　　　"weapon": {
　　　　　　　　　　　　　　　"name": ブキ名
　　　　　　　　　　　　　　　"special": {
　　　　　　　　　　　　　　　　　　"name": スペシャルウエポン
　　　　　　　　　　　　　　　} 
　　　　　　　　　　　　　　　"sub": {
　　　　　　　　　　　　　　　　　　"name": サブウエポン
　　　　　　　　　　　　　　　}
　　　　　　　　　　　　}
　　　　　　　　　}
　　　　　　}
　　　},
　　　{ .... }
　　　]
}
```


#Codableを使用して戦績を取得する。
返ってくるデータはそのままだと、取得できないためCodableを使用しキーごとに分解させる必要があります。

基本的に、key: 型名でキーの宣言を行えばよいが、配列の場合は、key：[型名]にする必要があります。

```
struct iksmData : Codable {
　　　let results: [results]
}

//各戦績
struct results : Codable {
　　　let battle_number: String
　　　let rule: name
　　　let stage: name
　　　let udemae: name?
　　　let estimate_x_power: Double?
　　　let my_team_result: name
　　　let player_result: player_result
}

//プレイヤーの戦績
struct player_result : Codable {
　　　let assist_count: Int
　　　let death_count: Int
　　　let kill_count: Int
　　　let special_count: Int
　　　let player : player
}

//プレイヤーの情報
struct player : Codable {
　　　let nickname: String        
　　　let weapon: weapon
}

//武器の情報
struct weapon : Codable {
　　　let name: String
　　　let special: name
　　　let sub: name
}
    
struct name : Codable {
　　　let name: String
}
```

estimate_x_power等はバトルによってキーが存在しない場合があるため、そのままだと分解できなくなりエラーになる。
そのため、型名の後に?をつけ、nullでも取得出来るようにする必要があります。

#JSONDecoderを使いデータを取得する。

JSONDecoder().decode(Codable, from: data)でデコードを行います。
Codableの型に合っていれば、Codableで宣言した値を取得できます。

```
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
　　　do {
　　　　　　//デコード
　　　　　　var resultData = try? JSONDecoder().decode(iksmData.self, from: data)

　　　} catch {
　　　　　　print(error)
　　　}
})
//タスク開始
task.resume()
```


取得したデータは以下のようにすれば確認できます。

```
print(resultData!.results[i].player_result.kill_count)
print(resultData!.results[i].player_result.assist_count)
print(resultData!.results[i].player_result.death_count)
print(resultData!.results[i].player_result.special_count)
```

#参考
https://qiita.com/dog_coro_zzz/items/788665a4c637cbb27807
https://qiita.com/yogita109/items/977e5c0e8d40795748d8
https://qiita.com/maebaru/items/fc2812df735473867382
https://qiita.com/UJIPOID/items/2c436a80f1167f7bcac0