Skip to content

Instantly share code, notes, and snippets.

@koromiko
Created June 9, 2021 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koromiko/f44f19d88143066d4e65bcc6b6470ff5 to your computer and use it in GitHub Desktop.
Save koromiko/f44f19d88143066d4e65bcc6b6470ff5 to your computer and use it in GitHub Desktop.
enum RequestError: Error {
case apiError(reason: String)
}
class AsyncJokeGenerator: AsyncSequence {
__consuming func makeAsyncIterator() -> AsyncIterator {
return AsyncIterator(numberOfJokes: numberOfJokes)
}
typealias Element = String
private let numberOfJokes: Int
init(numberOfJokes: Int) {
self.numberOfJokes = numberOfJokes
}
struct AsyncIterator: AsyncIteratorProtocol {
var numberOfJokes: Int = 0
mutating func next() async throws -> String? {
if numberOfJokes > 0 {
numberOfJokes -= 1
return try await giveMeAJoke()
} else {
return nil
}
}
private func giveMeAJoke() async throws -> String {
return try await getJSONResult(url: "https://api.chucknorris.io/jokes/random", key: "value")
}
private func getJSONResult(url: String, key: String) async throws -> String {
let (data, _) = try await URLSession.shared.data(from: URL(string: url)!, delegate: nil)
if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any],
let result = json[key] as? String {
return result
} else if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]],
let result = json.first?[key] as? String {
return result
} else {
throw RequestError.apiError(reason: "JSON parse error")
}
}
}
}
async {
for try await joke in AsyncJokeGenerator(numberOfJokes: 3) {
print(joke)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment