SwiftUIでいこう! - CombineでURLSession。
URLSessionの通常の書き方とCombineでの書き方が比較してあります
CombineでdataTaskPublisherを使いJsonのデータを取得しています。サイトのコードをそのまま実行してみます。
import Foundation
let qiitaURL = URL(string: "https://qiita.com/api/v2/items/a9ead7285d10aadf5643/likes")!
struct LGTM: Codable {
var created_at: String
var user: User
}
struct User: Codable {
var id: String
}
let session = URLSession.shared.dataTask(with: qiitaURL) {data, response, error in
if let error = error {
fatalError("Error: \(error.localizedDescription)")
}
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
fatalError("Error: invalid HTTP response code")
}
guard let data = data else {
fatalError("Error: missing response data")
}
do {
let lgtms = try JSONDecoder().decode([LGTM].self, from: data)
lgtms.forEach{ lgtm in
print("username: \(lgtm.user.id), created_at \(lgtm.created_at)")
}
}
catch {
print("Error: \(error.localizedDescription)")
}
}
session.resume()
実行すると、
username: h1d3mun3, created_at 2020-12-16T17:27:07+09:00
username: st43, created_at 2020-09-25T09:52:25+09:00
username: yo-okazawa, created_at 2020-09-23T12:22:08+09:00
username: LittleWat, created_at 2020-09-23T11:36:11+09:00
username: funnything, created_at 2020-09-23T10:35:44+09:00
username: shigeshige0914, created_at 2020-09-23T07:47:35+09:00
Jsonデータを指定URLより一部を取り出すと、
[
{
"created_at": "2020-12-16T17:27:07+09:00",
"user": {
"description": "iOS App Developer / Swift / RxSwift",
"facebook_id": "",
"followees_count": 9,
"followers_count": 11,
"github_login_name": null,
"id": "h1d3mun3",
"items_count": 8,
"linkedin_id": "",
"location": "Tokyo, Japan",
"name": "Hidemune Takahashi",
"organization": "",
"permanent_id": 203170,
"profile_image_url": "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203170/profile-images/1606447281",
"team_only": false,
"twitter_screen_name": null,
"website_url": ""
}
},
となっていて、"user" の"id"と"created_at"データが取り出されいるのが分かります。
Combineでも同じことをすると、
import Foundation
import Combine
let qiitaURL = URL(string: "https://qiita.com/api/v2/items/a9ead7285d10aadf5643/likes")!
struct LGTM: Codable {
var created_at: String
var user: User
}
struct User: Codable {
var id: String
}
var cancellable = URLSession.shared
.dataTaskPublisher(for: qiitaURL)
.tryMap { element -> Data in
guard let httpResponse = element.response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
return element.data
}
.decode(type: [LGTM].self, decoder: JSONDecoder())
.sink(receiveCompletion: {
print("complete! \($0)")
}, receiveValue: { lgtms in
lgtms.forEach{ lgtm in
print("username: \(lgtm.user.id), created_at \(lgtm.created_at)")
}
})
これを実行すると、
username: h1d3mun3, created_at 2020-12-16T17:27:07+09:00
username: st43, created_at 2020-09-25T09:52:25+09:00
username: yo-okazawa, created_at 2020-09-23T12:22:08+09:00
username: LittleWat, created_at 2020-09-23T11:36:11+09:00
username: funnything, created_at 2020-09-23T10:35:44+09:00
username: shigeshige0914, created_at 2020-09-23T07:47:35+09:00
complete! finished
同じように、"user" の"id"と"created_at"データが取り出されいるのが分かります。
Json形式のデータを取得します。Jsonデータとしては大項目としては
"created"、"user"
この2つ。そして、"user"の中にデータがたくさんあリますが、"id"を取り出すように Codableに準拠したstructを作っています。
struct LGTM: Codable {
var created_at: String
var user: User
}
そして、
var user: User
の部分はさらにstructをつくります。
struct User: Codable {
var id: String
}
これでデータの読み込み準備ができました。
URLSessionを使ってデータを読み込みdataTask、または、dataTaskPublisherを使ってデータ処理します。dataTaskPublisherは完結に書くことができます。
.dataTaskPublisher(for: qiitaURL)
.tryMap { element -> Data in
guard let httpResponse = element.response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
return element.data
}
.decode(type: [LGTM].self, decoder: JSONDecoder())
の部分でデータを受けJsonをパース、使える状態とします。そして、使い方は".sink"以下
.sink(receiveCompletion: {
print("complete! \($0)")
}, receiveValue: { lgtms in
lgtms.forEach{ lgtm in
print("username: \(lgtm.user.id), created_at \(lgtm.created_at)")
}
これでデータを取り出すことができます。以下参考サイトです。
この記事が気に入ったらサポートをしてみませんか?