Ich habe untersucht, wie man URLSession normal schreibt und wie man in Combine schreibt.
Wir werden die LGTM-Akquisitions-API von Qiita als Beispiel verwenden. Referenz: LGTM und Ansicht Ihres Artikels mit der Qiita-API abrufen. --Qiita
Derzeit erhält LGTM ungefähr 5 Artikel LGTM.
https://qiita.com/api/v2/items/a9ead7285d10aadf5643/likes
Sie können es erhalten, indem Sie diese URL mit GET treffen.
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()
Der Typ von "let session" ist "URLSessionDataTask". Kommunizieren Sie, indem Sie den Lebenslauf von "URLSessionDataTask" aufrufen.
Die Definition der URLSession-Methode dataTask lautet wie folgt.
open func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
Die Beschreibung in Kombinieren lautet wie folgt.
import Foundation
import Combine
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)")
}
})
Die Verarbeitung hat sich ein wenig geändert, aber ich bin der Meinung, dass Combine im CompletionHandler weniger Verarbeitung hat und die Aussichten besser sind.
Tips
Wenn Sie etwas angeben, das nicht im Json-Feldnamen enthalten ist, "Fehler: Die Daten konnten nicht gelesen werden, weil sie fehlen." Und Json Decoder gibt einen Fehler aus.
Zum Beispiel, wenn struct wie folgt definiert ist.
struct User: Codable {
var id: String
var aaa: String
}
In einem solchen Fall ist es möglich, einen Fehler durch Eingabe von "nil" zu verhindern, indem der möglicherweise nicht vorhandene Feldname auf "Optional" gesetzt wird.
struct User: Codable {
var id: String
var aaa: String?
}
URLSession.shared ist ein Singleton, den Sie verwenden können, wenn Sie schnell schreiben möchten. Da es mit dem Standardverhalten funktioniert, kann keine erweiterte Verarbeitung durchgeführt werden.
shared | Apple Developer Documentation
Es gibt nur das Abschlussargument an.
Es funktioniert auch dann, wenn kein -> Data
Teil vorhanden ist.
Closures — The Swift Programming Language (Swift 5.3)
In Combine wird der URLSession-Abonnementprozess derzeit von forEach verschachtelt.
.decode(type: [LGTM].self, decoder: JSONDecoder())
.sink(receiveValue: { lgtms in
lgtms.forEach{ lgtm in
print("username: \(lgtm.user.id), created_at \(lgtm.created_at)")
}
}
Sie können "flatMap" verwenden, um diese Verschachtelung zu entfernen.
.decode(type: [LGTM].self, decoder: JSONDecoder())
.flatMap {$0.publisher}
.sink(receiveCompletion: {
print("complete! \($0)")
}, receiveValue: { lgtm in
print("username: \(lgtm.user.id), created_at \(lgtm.created_at)")
})
Recommended Posts