はじめに
Moyaを触っておきたいと思ったので、GitHubAPIを使用して簡単なサンプルを作成してみました。
超カンタンに自分の備忘録としてまとめておきます。
Moyaとは?
MoyaはAlamofireを直接さわることなく、ネットワークレイヤーを抽象化してくれるライブラリだそう。
Alamofireをラッピングしているということで、簡易的にAPI通信できるところが魅力みたいですね!
まず触ってみます。
作成するサンプル
リポジトリ検索のAPIを叩いて、TableViewに表示し
CellをタップするとWebビューが立ち上がり、GitHubに飛ぶ
って感じです。
今回はswiftと検索した場合。
import Foundation
import Moya
enum GithubError: Error {
case error
}
enum GithubAPI {
case user
}
extension GithubAPI: TargetType {
var baseURL: URL {
guard let url = URL(string: "https://api.github.com/search/repositories?q=swift&sort=stars") else {
fatalError("base URL error")
}
return url
}
var path: String {
switch self {
case .user:
return ""
}
}
var method: Moya.Method {
return Moya.Method.get
}
var sampleData: Data {
return Data()
}
var task: Task {
return .requestPlain
}
var headers: [String : String]? {
return nil
}
func get(completion: ((Result<[GithubModel], GithubError>) -> Void)? = nil) {
let provider = MoyaProvider<GithubAPI>()
provider.request(.user){ result in
print(result)
switch result {
case.success(let response):
let data = response.data
guard let githubResponse = try? JSONDecoder().decode(GithubResponse.self, from: data),
let models = githubResponse.items else {
return
}
completion?(.success(models))
case.failure(let error):
completion?(.failure(GithubError.error))
}
}
}
}
続いて表示するViewController
viewDidLoadでAPIのgetメソッドを呼んでいます。
他の方のサンプルをみたところ、ViewControllerでMoyaProviderのインスタンスを作っていましたが
Controllerと切り離したかった為、APIの中で定義しました。
import UIKit
final class ListViewController: UIViewController {
@IBOutlet private weak var indicator: UIActivityIndicatorView!
@IBOutlet private weak var tableView: UITableView! {
didSet {
tableView.register(UINib.init(nibName: TableViewCell.className, bundle: nil), forCellReuseIdentifier: TableViewCell.className)
tableView.delegate = self
tableView.dataSource = self
}
}
private var items: [GithubModel] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.isHidden = false
indicator.isHidden = true
DispatchQueue.main.async {
self.indicator.isHidden = true
self.tableView.isHidden = false
GithubAPI.user.get { result in
switch result {
case.failure(let error):
print(error)
case.success(let response):
print(response)
self.items = response
self.tableView.reloadData()
}
}
}
}
}
extension ListViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
Router.shared.showWeb(from: self, githubModel: items[indexPath.item])
}
}
extension ListViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.className) as? TableViewCell else {
fatalError()
}
let githubModel = items[indexPath.item]
cell.configure(githubModel: githubModel)
return cell
}
}
終わりに
今回は超シンプルなサンプルでMoyaに触れてみました。
enumで複数エンドポイントを定義したり、RxSwiftに対応していたり
色々できるそうですね。
ソースコードは下記にアップしています。
https://github.com/taro-ken/Moya-Sample
間違っている箇所もあるかと思いますが、その際はコメントいただければと思います。