-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathOAuth+Monitor.swift
More file actions
56 lines (46 loc) · 1.7 KB
/
Copy pathOAuth+Monitor.swift
File metadata and controls
56 lines (46 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//
// OAuth+Monitor.swift
// OAuthKit
//
// Created by Kevin McKee
//
import Foundation
@testable import OAuthKit
extension OAuth {
/// Provides a testing utility to stream an oauth state until it's received an authorization.
/// This is necessary because a unit test can potentially die as an asynchronous request is received that
/// inserts an authorization record into the keychain. This allows us to keep the keychain clean and not get littered with test records.
@MainActor
class Monitor {
typealias OAuthStateAsyncStream = AsyncStream<OAuth.State>
private let oauth: OAuth
var continuation: OAuthStateAsyncStream.Continuation?
lazy var stream: OAuthStateAsyncStream = {
AsyncStream(bufferingPolicy: .bufferingNewest(1)) { continuation in
self.continuation = continuation
waitForNextValue()
}
}()
/// Initialzation.
/// - Parameter oauth: the oauth state to stream
init(oauth: OAuth) {
self.oauth = oauth
}
deinit {
continuation?.finish()
}
/// Waits for the next state value to be received. This will continue until we've received an `.authorized` state.
private func waitForNextValue() {
Task {
let state = oauth.state
continuation?.yield(state)
switch state {
case .empty, .error, .authorizing, .requestingAccessToken, .requestingDeviceCode, .receivedDeviceCode:
waitForNextValue()
case .authorized(_, _):
continuation?.finish()
}
}
}
}
}