LoginSignup
6
5

More than 3 years have passed since last update.

【Swift】QiitaAPIアプリで学んだこと

Last updated at Posted at 2021-03-23

はじめに

自作アプリ、QiitaAPIで学んだことをまとめます。(自分用メモ)

GitHubリンク

学んだこと

API通信をしている処理とViewControllerの分離

悪い例

QiitaViewController
func fetchQiitaAPI() {
    guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=10") else {
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if let error = error {
            print(error)
            return
        }
        guard let data = data else {
            return
        }
        do {
            let qiitas = try JSONDecoder().decode([Qiita].self, from: data)
            self.qiitas = qiitas
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        } catch {
            print(error)
        }
    }
    task.resume()
}

良い例

QiitaViewController
private func fetchQiitaAPI() {
    //メイン処理
    QiitaAPI.shared.fetchQiitaAPI(page: pageCount) { result in
        switch result {
        case .success(let qiitas):
            self.qiitas = qiitas
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        case .failure(let error):
            print(error)
        }
    }

}
QiitaAPI
typealias ResultHandler<T> = (Result<T, APIError>) -> Void

class QiitaAPI {
    //シングルトンで
    static let shared = QiitaAPI()
    private init() { }

    func fetchQiitaAPI(page: Int, handler: @escaping ResultHandler<[Qiita]>) {
        //メイン処理
        guard let url = URL(string: "https://qiita.com/api/v2/items?page=1&per_page=\(page)") else {
            handler(.failure(NetworkError.invalidURL))
            return
        }
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let error = error {
                handler(.failure(error))
            }
            guard let data = data else {
                handler(.failure(NetworkError.unknown))
                return
            }
            do {
                let qiitas = try JSONDecoder().decode([Qiita].self, from: data)
                handler(.success(qiitas))
            } catch {
                handler(.failure(NetworkError.invalidResponse))
            }
        }
        task.resume()
    }

}

typealias ResultHandler<T> = (Result<T, Error>) -> Voidとおくのもポイント

JSONがスネークケースの時の対応

Model
enum CodingKeys: String, CodingKey {
    case title = "title"
    case createdAt = "created_at"
    case user = "user"
}

CodingKeysを設定する

二つ目の方法として、このようにしてあげれば自動でスネークケースに変換してくれます。

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

おわりに

おわりです。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5