Last active
November 5, 2023 13:13
-
-
Save profh/e1d53ad2079f4e9fe4799679de8ca9c1 to your computer and use it in GitHub Desktop.
Combine Exercise Solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// One solution to the class exercise | |
import UIKit | |
import Combine | |
import PlaygroundSupport | |
// This playground will execute indefinetly in order to give our | |
// async operations enough time to execute. | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
// --- Creating a publisher for performing a network request --- | |
// Note: set a retry automatically (3x) if request fails | |
let url = URL(string: "https://api.github.com/search/repositories?q=language:swift&sort=stars&order=desc")! | |
let publisher = URLSession.shared | |
.dataTaskPublisher(for: url) | |
.retry(3) | |
// --- Bringing back our old friends --- | |
struct Repositories: Codable { | |
let items: [Repository] | |
enum CodingKeys: String, CodingKey { | |
case items | |
} | |
} | |
struct Repository: Codable, Identifiable { | |
let id: Int | |
let name: String | |
let htmlURL: String | |
let itemDescription: String? | |
enum CodingKeys: String, CodingKey { | |
case id | |
case name | |
case htmlURL = "html_url" | |
case itemDescription = "description" | |
} | |
} | |
// --- Constructing a reactive chain of operators --- | |
let repoPublisher = publisher | |
.map(\.data) | |
.decode( | |
type: Repositories.self, | |
decoder: JSONDecoder() | |
) | |
.receive(on: DispatchQueue.main) | |
// --- Updating our UI based on our reactive chain --- | |
// Some UI labels that we want to render our data using: | |
let nameLabel = UILabel() | |
let urlLabel = UILabel() | |
let errorLabel = UILabel() | |
let cancellableRepoSubscriber = repoPublisher.sink( | |
receiveCompletion: { completion in | |
switch completion { | |
case .failure(let error): | |
// Rendering a description of the error that was encountered: | |
print("ErrorMsg: \(error.localizedDescription)") | |
case .finished: | |
break | |
} | |
}, | |
receiveValue: { repos in | |
// Rendering each repository's name and url: | |
_ = repos.items.map { repo in | |
print("Name: \(repo.name)") | |
print("URL: \(repo.htmlURL)") | |
print("-----") | |
} | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment