QiitaのAPIにはトレンドを取得するAPIが存在しない
現在、SwiftUIでQiitaの記事を参照することができるクライアントアプリを作成中です。
トレンドの記事をリスト化して表示できたらいいなと思っていたらまさかのAPI自体提供されていない...
他のQiitaの記事でも同じようなことを実現させようと新たにQiitaのトレンドAPIを非公式で公開してるエンジニアも...
今回iOSネイティブアプリを作成しているので、Swiftだけで解決できないか試してみました!
SwiftSoup
- HTMLをパース(解析)してくれるライブラリ
- https://github.com/scinfu/SwiftSoup
- Cocoapods、Carthage、Swift Package Manager対応
Qiitaのトップページを解析する
import SwiftSoup
import Combine
// Qiitaのページ(1日)
let urlString = "https://qiita.com/"
// 週間: https://qiita.com/?scope=weekly
// 月間: https://qiita.com/?scope=monthly
// タスクの初期化
var task = : AnyCancellable?
// URLに変換
let url = URL(string: urlString)!
// HTMLを取得
task = URLSession.shared.dataTaskPublisher(for: url)
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("成功")
case let .failure(error):
print(error)
}
}, receiveValue: { data, _ in
do {
let text = String(data: data, encoding: .utf8)!
// ここからSwiftSoupでパース
let doc: Document = try SwiftSoup.parse(text)
let link: Element = try doc.select("div[data-hyperapp-app=Trend]").first()!
let json: Data = try link.attr("data-hyperapp-props").data(using: .utf8)!
// Codableでデコード
let response = try JSONDecoder()
.decode(TrendResponse.self,
from: json)
/// edgesにトレンドの記事が格納される
print(response.trend.edges)
} catch {
print("エラー")
}
})
Codable
struct TrendResponse: Codable {
let scope: String
var trend: Trend
}
struct Trend: Codable {
let edges: [Edges]
}
struct Edges: Codable {
let followingLikers: [Author]
let isLikedByViewer: Bool
let isNewArrival: Bool
let hasCodeBlock: Bool
let node: Node
}
struct Node: Codable {
let createdAt: String
let likesCount: Int
let title: String
let uuid: String
let author: Author
}
struct Author: Codable {
let profileImageUrl: String
let urlName: String
}
完成した画面
まとめ
- SwiftでHTMLを取得しパースすることで実現することができた。
- 現在、SwiftUIでクライアントアプリを絶賛開発中です。
- TestFlightでテスト配信もしているので、ご興味がある方は、コメントまたは連絡ください!