Swift

Swift: APIKitとHimotokiの基本のき!


今回はAPIKitとHimotokiの基本的な使用方法を解説していきます!

前回の記事

Swift3: APIKitの超簡単な使用方法 の続きになっています。

 

Himotokiについて

Himotokiは一言でいうとjsonデコーダーライブラリです

はい

 

jsonデコーダーなんていってもわからないですよね。

僕も「?」って感じでした。

 

ざっくりいうなら、json形式のデータをSwiftのコードにすることです。

Swiftのコードにすることでアプリ開発をしやすくなります。

ただのjson形式のデータをSwiftのクラスに落とし込むことで扱いやすくなることはイメージしやすいと思います。

前回の記事では、Githubの特定のUserのリポジトリのデータを取得するものを作成しました。

その場合、Swiftでリポジトリのクラスを扱えるようにした方が色々便利です。

 

それでは、リポジトリクラスを作成していきます!

 

Repository(リポジトリ)クラスを作成

クラスと言いつつ、構造体で作ります。

構造体ってなに??という方はこちらの記事をご覧ください。

構造体について

構造体の方がそれっぽい!ですね。

 

Repository.swiftというファイルを作成しました。

import Himotoki

struct Repository: Decodable {

    let fullName: String

    static func decode(_ e: Extractor) throws -> Repository {

        return try Repository(

            fullName: e <| "full_name"

        )

    }

}

 

struct Repository: Decodable {}

Repositoryという構造体をDecodableというHimotokiのプロトコルに準拠させます。

Himotokiを使用する上で必須の記述です。

 

let fullName: String

こちらのfullNameというプロパティはUser名とリポジトリ名が一緒になっているデータです。

ほんとはもっと色々なプロパティを設定して色々なデータを利用した方がそれっぽいのですが、

余計なことをするとわかりづらくなるので今回を一つだけで進めます。

 

こちらに詳しく乗っているのでご参照ください!

https://developer.github.com/v3/repos/#list-user-repositories

 

 

 

static func decode(_ e: Extractor) throws -> Repository {

ここが最重要です!

decodeの際の処理をここに記述します。

「デコードの結果、jsonデータがRepositoryになる」
という記述をするところなので、返り値はRepositoryですね!

 

でもやっぱり難しいのは、

fullName: e <| “full_name”
のところですよね。

fullName(Repositoryのプロパティ)  : e <|   (値の抽出)    “full_name”(jsonデータのキー)

Himotokiでは

e <| “jsonデータのキー” というかなり特殊な記述方法をします。

つまり「RepositoryのプロパティfullName」に「jsonデータのキー”full_name”を使用することで手に入るvalue」を代入しているのです!!

 

これはもう覚えるしかありません。。。

 

あとは前の記事とは返ってくるデータをデコードするという違いが出てきたので、

FetchRepositoryRequestの方にも変更を加えてあげます。

 

FetchRepositoryRequestがHimotokiに対応するッ!

struct FetchRepositoryRequest: GitHubRequest {

    var userName: String

    var path: String {

        return "/users/\(userName)/repos"

    }

    typealias Response = [Repository]    

    var method: HTTPMethod {

        return .get

    }


    func response(from object: Any, urlResponse: HTTPURLResponse) throws -> FetchRepositoryRequest.Response {

        return try decodeArray(object)

    }

}

 

変わったところ1、typealias Response = [Repository]

ResponseはAnyにしていましたが、独自で作ったRepository構造体に設定しました。

注意しなければいけないのは、今回返ってくる値は特定のUserの持っているRepositoryですが、

正確にはRepositoriesです。Userの持っている全てのRepositoryです。

つまり配列なのです。

なので、[]で囲っているわけですね。

 

変わったところ2、func response(from …

変わったところはreturnの部分ですね。

tryに関しては一旦置いておきますが、今度記事を書きたいと思います。。。とりあえず無視してください。

難しいのはdecodeArray(object)ですよね。

このエンドポイントでdecodeするjsonデータは配列なので、decodeArrayを使用します。引数にはデコードするobjectを代入します。

もし単発のデータであったり、辞書型であったりしたら、また別のメソッドを使用します。

 

なんとたったこれだけでいい感じでデコードしてくれます!!

 

あとは取得するデータが配列なので、UITableViewなどを使用するといい感じに表示できます。

 

ViewController.swiftを軽く編集

全体的なコードはこんな感じです。

tableViewってなんやねん・・・

という方はこちら!

swift3:初心者向け!UITableViewの使い方:delegate・datasourceについて

import UIKit

import APIKit

import Himotoki

class ViewController: UIViewController, UITableViewDataSource {

    

    var repoArray: [Repository] = []

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {

        super.viewDidLoad()

        tableView.dataSource = self

        Session.send(FetchRepositoryRequest(userName: "sasao")) { result in

            switch result {

                case .success(let res):

                    self.repoArray = res

                    self.tableView.reloadData()

                

                case .failure(let err):

                    print("しくった\(err)")

            }

        }

        

    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

    }

    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return repoArray.count

    }

    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        cell.textLabel?.text = repoArray[indexPath.row].fullName

        return cell

    }

}

 

var repoArray: [Repository] = []

RepositoryをtableViewに表示させたいので、比較的グローバルな層に配列を用意しておきます。

 

.success

この辺にも少し変更を加えました。

resにはデコードされた[Repository]が入っているので、そのままrepoArrayに代入します。

そしていつものtableView.reloadData()ですね。

 

次回

次はこれにRxSwiftを混ぜていきたいと思います!!

待っててくだせぇ

 

 

 


ABOUT ME
ささお
3年目iOSエンジニア。 スタートアップで働いておりやす。 プログラミングスクールとエンジニアのキャリアを考えたい。 作ったアプリ - https://apps.apple.com/us/app/loverprofile/id1463563845?l=ja&ls=1