##背景
iOSのアプリ設計で復習したいと思いに、Qiitaの記事を表示させるアプリを作成しようと思いました。この記事ではAPIからデータを取ってきて表示させるまでを書いていきたいと思います。このアプリで学んだことをいくつかに分けて説明していきますので次回記事が出来次第リンク先を載せます。
完成図
APIからデータを取得する
Qiitaが提供してくれているAPIを使用します。
APIのリンク先
今回は作成日時から50個をQiitaが提供しているAPIから取得してみたいと思います。
なので下記の箇所を使用したいと思います。
GET /api/v2/items
記事の一覧を作成日時の降順で返します。
per_page
1ページあたりに含まれる要素数 (1から100まで)
Example: 20
Type: string
Pattern: /^[0-9]+$/
[
{
"rendered_body": "<h1>Example</h1>",
"body": "# Example",
"coediting": false,
"comments_count": 100,
"created_at": "2000-01-01T00:00:00+00:00",
"group": {
"created_at": "2000-01-01T00:00:00+00:00",
"id": 1,
"name": "Dev",
"private": false,
"updated_at": "2000-01-01T00:00:00+00:00",
"url_name": "dev"
},
"id": "4bd431809afb1bb99e4f",
"likes_count": 100,
"private": false,
"reactions_count": 100,
"tags": [
{
"name": "Ruby",
"versions": [
"0.0.1"
]
}
],
"title": "Example title",
"updated_at": "2000-01-01T00:00:00+00:00",
"url": "https://qiita.com/yaotti/items/4bd431809afb1bb99e4f",
"user": {
"description": "Hello, world.",
"facebook_id": "yaotti",
"followees_count": 100,
"followers_count": 200,
"github_login_name": "yaotti",
"id": "yaotti",
"items_count": 300,
"linkedin_id": "yaotti",
"location": "Tokyo, Japan",
"name": "Hiroshige Umino",
"organization": "Increments Inc",
"permanent_id": 1,
"profile_image_url": "https://si0.twimg.com/profile_images/2309761038/1ijg13pfs0dg84sk2y0h_normal.jpeg",
"team_only": false,
"twitter_screen_name": "yaotti",
"website_url": "http://yaotti.hatenablog.com"
},
"page_views_count": 100
}
]
Codableを使ってJSONを変換させる
API通信でデータを取得する際に、JSONで受け取ってモデルや構造体に変換する手法が一般的です。swiftyjsonなどを用いてパースしてjsonの値を取ってきたりしていました。Swift4からはswiftが提供したCodableを使うことでライブラリを使わずシンプルに記述できるようになりました。
今回はそちらのCodableを使っていきます。
使い方は下記の記事を参考にしました。
[Swift4 Codableがすごすぎた件]
(https://qiita.com/UJIPOID/items/2c436a80f1167f7bcac0)
今回は上記のQiitaApiから記事のタイトルとユーザー名を取得しました。
struct QiitaStruct: Codable {
var title: String
var user: User
struct User: Codable {
var name: String
}
}
APIをURLSessionを使って叩く
connpassAPIを叩くためにURLSessionを使いました。
URLSessionとはリクエストを受けて通信を行うクラスです。
またURLQueryItemを使うことでURLのクエリストリングを追加して、ページの要素数を50までと指定しました。
例)"https://qiita.com/api/v2/items" -> "https://qiita.com/api/v2/items?per_page=50"
class QiitaViewModel {
static func fetchArticle(completion: @escaping ([QiitaStruct]) -> Swift.Void) {
let url = "https://qiita.com/api/v2/items"
guard var urlComponents = URLComponents(string: url) else {
return
}
urlComponents.queryItems = [
URLQueryItem(name: "per_page", value: "50"),
]
let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in
guard let jsonData = data else {
return
}
do {
let articles = try JSONDecoder().decode([QiitaStruct].self, from: jsonData)
completion(articles)
} catch {
print(error.localizedDescription)
}
}
task.resume()
}
}
tableviewにデータを表示させる
今回はextensionを使いクラスに定義を追加しました。
拡張先ではclassでQiitaStruct
で取ってきた値をarticle
に格納してそれを使いcellに代入する処理をしています。
extension QiitaViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
let article = articles[indexPath.row]
cell.textLabel?.text = article.title
cell.detailTextLabel?.text = article.user.name
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return articles.count
}
}
## 全体的なコード
コードは下記になります。
struct QiitaStruct: Codable {
var title: String
var user: User
struct User: Codable {
var name: String
}
}
class QiitaViewModel {
static func fetchArticle(completion: @escaping ([QiitaStruct]) -> Swift.Void) {
let url = "https://qiita.com/api/v2/items"
guard var urlComponents = URLComponents(string: url) else {
return
}
urlComponents.queryItems = [
URLQueryItem(name: "per_page", value: "50"),
]
let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in
guard let jsonData = data else {
return
}
do {
let articles = try JSONDecoder().decode([QiitaStruct].self, from: jsonData)
completion(articles)
} catch {
print(error.localizedDescription)
}
}
task.resume()
}
}
class QiitaViewController: UIViewController {
private var tableView = UITableView()
fileprivate var articles: [QiitaStruct] = []
override func viewDidLoad() {
super.viewDidLoad()
self.title = "QiitaAPI"
tableView.dataSource = self
tableView.frame = view.frame
view.addSubview(tableView)
QiitaViewModel.fetchArticle(completion: { (articles) in
self.articles = articles
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
extension QiitaViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
let article = articles[indexPath.row]
cell.textLabel?.text = article.title
cell.detailTextLabel?.text = article.user.name
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return articles.count
}
}
次にやること
次回はcellの大きさなどを変更していこうと思います。