まだAPIで消耗しているの?[Part3-1]

Part2の続きです

Part2で作成したURLモデルを使用します。


[Part3]でやること

●得れるモノ:YouTubeのAPIを叩いて、サムネイルを取得する

●具体的にすること:自分のアプリからAPIを叩いて、JSONを取得し、アプリに取り込みます。

●対象者:Part1&Part2を理解した人、cocoapodsの導入など、主にSwiftの簡単な開発がわかる方

●使用するライブラリー:Alamofire

●使用する技術:tableView、Codable、Struct、Search


環境

Swift4.2

Xcode 10.1


では開発やっていきましょう👍!!


APIを叩く前の準備


①CocoapodsのInstall

●Alamofireを導入

スクリーンショット 2019-04-23 13.11.43.png

今回使用するライブラリは、Alamofireです。

初めて使用する方は,なんだそれってなりますよね。

大丈夫です。安心してください。説明します。


Alamofireとは?

簡単に言うと、②と④の処理をSwiftで楽に書けるように補ってくれるものです👍

以上。(もっと詳しくしりたい方がいたら調べて見てください!)

無題のプレゼンテーション (3).jpg


②storyboardとViewController作成

Storyboard

スクリーンショット 2019-04-23 23.47.52.png

●ViewController

tableViewとsearchControllerを使用しました。


ViewController.swift

import UIKit

class ViewController: UIViewController{

//Outlets
@IBOutlet weak var tableView: UITableView!

//MARK: Properties
let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
super.viewDidLoad()

setupSearchController()

tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()

}

//MARk: Searchcontroller
func setupSearchController() {

searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
searchController.searchBar.placeholder = "チャンネル名"
searchController.searchBar.backgroundColor = .white
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
searchController.dimsBackgroundDuringPresentation = false

}

}

//MARK: tableView拡張
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!

let thumbnailsImage = cell.viewWithTag(1) as! UIImageView
let thumbnailsTitleName = cell.viewWithTag(2) as! UILabel

return cell
}

func tableView(_ table: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
return 290
}

}

//MARK: searchController拡張
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
print("更新")
}
}



JSONに対応したモデルのファイルを作成する

Part2で作成したモデルを使用するときが来ました!!!!

まずはそのまま、コピペして見ましょう👍


ApiClients.swift

import Foundation

struct Rooter: Codable {
let kind, etag, nextPageToken, regionCode: String
let pageInfo: PageInfo
let items: [Item]
}

struct Item: Codable {
let kind, etag: String
let id: ID
let snippet: Snippet
}

struct ID: Codable {
let kind: String
let channelID, videoID: String?

enum CodingKeys: String, CodingKey {
case kind
case channelID = "channelId"
case videoID = "videoId"
}
}

struct Snippet: Codable {
let publishedAt, channelID, title, description: String
let thumbnails: Thumbnails
let channelTitle, liveBroadcastContent: String

enum CodingKeys: String, CodingKey {
case publishedAt
case channelID = "channelId"
case title, description, thumbnails, channelTitle, liveBroadcastContent
}
}

struct Thumbnails: Codable {
let thumbnailsDefault, medium, high: Default

enum CodingKeys: String, CodingKey {
case thumbnailsDefault = "default"
case medium, high
}
}

struct Default: Codable {
let url: String
let width, height: Int?
}

struct PageInfo: Codable {
let totalResults, resultsPerPage: Int
}


まあ、なんのこっちゃわからないと思うので解説しまっせ。


構造(モデル)について解説


①Codableとは?

→JSONのデータをアプリで実装しやすいデータの形に変えるプロトコルです

使いやすいように型宣言できるって感じですね。(JSONに合わせないといけないですが)

例)String, Int, Double, Data, Date, URL、Array, Dictionary, Optional


詳しくはこちら

https://qiita.com/s_emoto/items/deda5abcb0adc2217e86



②CodingKeyとは?

→JSONとkeyを一致させて使用できるようにすること。

んー。なんとなくわかりにくいなあ。

例えば、swift扱う際で命名上、最初の文字を大文字にしたくないなどの理由でJSONのKeyとは違う形で使いときに使用します。


Json

{

"Mario":"マリオ"
}



ApiClients.swift

struct Nintendo: Codable {

mario: String
enum CodingKeys: String, CodingKey {
case mario = "Mario"
}
}


こんな感じに使います!(そのままJSONのKey通りに書き込めば、CodingKeyは必要ありません。)

CodingKeyはenumとcaseを使用し、この書き方が固定です!


③JSONがDictionary型かArray型か確かめる

→JSONを取り出すときのモデルを作成する際には、もともとのJSONの形がなんなのか確認することが重要です。


Dictionary型

let json = """

{
"mario": "マリオ",
"details": {
"color": "赤い",
"brother": "兄"
}
}
"""
この場合で、jsonを扱うとき
→let character:json


Array型

let json = """

[
{
"mario": "マリオ",
"details": {
"color": "赤い",
"brother": "兄"
}
}
]
"""
この場合で、jsonを扱うとき
→let character:[json]

こんな感じになっているので、型には気をつけないといけません。

今回のYoutubeのJSONならば、itemに気をつけないといけません!!!


モデルの中の流れ

→今回はサムネイルの画像とタイトルが欲しいので以下の順番でモデルの中を下っていってます。

無題のプレゼンテーション (4).jpg

これ以外でいらない部分は除いてしまいます


ApiClients.swift

import Foundation

struct Rooter: Codable {
let items: [Item]
}

struct Item: Codable {
let snippet: Snippet
}

struct Snippet: Codable {
let publishedAt, channelID, title, description: String
let thumbnails: Thumbnails
enum CodingKeys: String, CodingKey {
case publishedAt
case channelID = "channelId"
case title, description, thumbnails
}
}

struct Thumbnails: Codable {
let thumbnailsDefault, medium, high: Default

enum CodingKeys: String, CodingKey {
case thumbnailsDefault = "default"
case medium, high
}
}

struct Default: Codable {
let url: String
let width, height: Int?
}


これでAPIを叩く準備がSwiftで整いました。


予告:Part3-2

次回はAlamofireを使用してAPIを取得します。

また、次でYouTubeのAPI編は終了です!

自由にYouTubeのAPIを叩けるようになりましょう👍