File tree Expand file tree Collapse file tree 4 files changed +88
-21
lines changed Expand file tree Collapse file tree 4 files changed +88
-21
lines changed Original file line number Diff line number Diff line change @@ -5,24 +5,6 @@ import Foundation
5
5
import FoundationNetworking
6
6
#endif
7
7
8
- public final class AuthStateChangeListenerHandle {
9
- var onCancel : ( @Sendable ( ) -> Void ) ?
10
-
11
- public func cancel( ) {
12
- onCancel ? ( )
13
- onCancel = nil
14
- }
15
-
16
- deinit {
17
- cancel ( )
18
- }
19
- }
20
-
21
- public typealias AuthStateChangeListener = @Sendable (
22
- _ event: AuthChangeEvent ,
23
- _ session: Session ?
24
- ) -> Void
25
-
26
8
public actor AuthClient {
27
9
/// FetchHandler is a type alias for asynchronous network request handling.
28
10
public typealias FetchHandler = @Sendable (
@@ -216,7 +198,7 @@ public actor AuthClient {
216
198
@discardableResult
217
199
public func onAuthStateChange(
218
200
_ listener: @escaping AuthStateChangeListener
219
- ) async -> AuthStateChangeListenerHandle {
201
+ ) async -> AuthStateChangeListenerRegistration {
220
202
let handle = eventEmitter. attachListener ( listener)
221
203
await emitInitialSession ( forHandle: handle)
222
204
return handle
@@ -240,7 +222,7 @@ public actor AuthClient {
240
222
}
241
223
242
224
continuation. onTermination = { _ in
243
- handle. cancel ( )
225
+ handle. remove ( )
244
226
}
245
227
}
246
228
Original file line number Diff line number Diff line change
1
+ //
2
+ // AuthStateChangeListener.swift
3
+ //
4
+ //
5
+ // Created by Guilherme Souza on 17/02/24.
6
+ //
7
+
8
+ import ConcurrencyExtras
9
+ import Foundation
10
+
11
+ /// A listener that can be removed by calling ``AuthStateChangeListenerRegistration/remove()``.
12
+ ///
13
+ /// - Note: Listener is automatically removed on deinit.
14
+ public protocol AuthStateChangeListenerRegistration : Sendable , AnyObject {
15
+ /// Removes the listener. After the initial call, subsequent calls have no effect.
16
+ func remove( )
17
+ }
18
+
19
+ final class AuthStateChangeListenerHandle : AuthStateChangeListenerRegistration {
20
+ let _onRemove = LockIsolated ( ( @Sendable ( ) - > Void) ? . none)
21
+
22
+ public func remove( ) {
23
+ _onRemove. withValue {
24
+ if $0 == nil {
25
+ return
26
+ }
27
+
28
+ $0 ? ( )
29
+ $0 = nil
30
+ }
31
+ }
32
+
33
+ deinit {
34
+ remove ( )
35
+ }
36
+ }
37
+
38
+ public typealias AuthStateChangeListener = @Sendable (
39
+ _ event: AuthChangeEvent ,
40
+ _ session: Session ?
41
+ ) -> Void
Original file line number Diff line number Diff line change @@ -35,7 +35,7 @@ final class DefaultEventEmitter: EventEmitter {
35
35
let handle = AuthStateChangeListenerHandle ( )
36
36
let key = ObjectIdentifier ( handle)
37
37
38
- handle. onCancel = { [ weak self] in
38
+ handle. _onRemove . setValue { [ weak self] in
39
39
self ? . listeners. withValue {
40
40
$0 [ key] = nil
41
41
}
Original file line number Diff line number Diff line change
1
+ //
2
+ // AuthStateChangeListenerHandleTests.swift
3
+ //
4
+ //
5
+ // Created by Guilherme Souza on 17/02/24.
6
+ //
7
+
8
+ @testable import Auth
9
+ import ConcurrencyExtras
10
+ import Foundation
11
+ import XCTest
12
+
13
+ final class AuthStateChangeListenerHandleTests : XCTestCase {
14
+ func testRemove( ) {
15
+ let handle = AuthStateChangeListenerHandle ( )
16
+
17
+ let onRemoveCallCount = LockIsolated ( 0 )
18
+ handle. _onRemove. setValue {
19
+ onRemoveCallCount. withValue {
20
+ $0 += 1
21
+ }
22
+ }
23
+
24
+ handle. remove ( )
25
+ handle. remove ( )
26
+
27
+ XCTAssertEqual ( onRemoveCallCount. value, 1 )
28
+ }
29
+
30
+ func testDeinit( ) {
31
+ var handle : AuthStateChangeListenerHandle ? = AuthStateChangeListenerHandle ( )
32
+
33
+ let onRemoveCallCount = LockIsolated ( 0 )
34
+ handle? . _onRemove. setValue {
35
+ onRemoveCallCount. withValue {
36
+ $0 += 1
37
+ }
38
+ }
39
+
40
+ handle = nil
41
+
42
+ XCTAssertEqual ( onRemoveCallCount. value, 1 )
43
+ }
44
+ }
You can’t perform that action at this time.
0 commit comments