@@ -29,29 +29,25 @@ open class HTTPSCallableResult: NSObject {
29
29
}
30
30
}
31
31
32
- /**
33
- * A `HTTPSCallable` is a reference to a particular Callable HTTPS trigger in Cloud Functions.
34
- */
32
+ /// A `HTTPSCallable` is a reference to a particular Callable HTTPS trigger in Cloud Functions.
35
33
@objc ( FIRHTTPSCallable)
36
- open class HTTPSCallable : NSObject {
34
+ open class HTTPSCallable : NSObject , @ unchecked Sendable {
37
35
// MARK: - Private Properties
38
36
39
- // The functions client to use for making calls.
40
- private let functions : Functions
41
-
42
- private let url : URL
43
-
44
- private let options : HTTPSCallableOptions ?
37
+ /// Until this class can be marked *checked* `Sendable`, it's implementation
38
+ /// is delegated to an auxialiary class that is checked Sendable.
39
+ private let sendableCallable : SendableHTTPSCallable
45
40
46
41
// MARK: - Public Properties
47
42
48
43
/// The timeout to use when calling the function. Defaults to 70 seconds.
49
- @objc open var timeoutInterval : TimeInterval = 70
44
+ @objc open var timeoutInterval : TimeInterval {
45
+ get { sendableCallable. timeoutInterval }
46
+ set { sendableCallable. timeoutInterval = newValue }
47
+ }
50
48
51
49
init ( functions: Functions , url: URL , options: HTTPSCallableOptions ? = nil ) {
52
- self . functions = functions
53
- self . url = url
54
- self . options = options
50
+ sendableCallable = SendableHTTPSCallable ( functions: functions, url: url, options: options)
55
51
}
56
52
57
53
/// Executes this Callable HTTPS trigger asynchronously.
@@ -79,36 +75,7 @@ open class HTTPSCallable: NSObject {
79
75
completion: @escaping @MainActor ( HTTPSCallableResult ? ,
80
76
Error ? )
81
77
-> Void ) {
82
- if #available( iOS 13 , macCatalyst 13 , macOS 10 . 15 , tvOS 13 , watchOS 7 , * ) {
83
- Task {
84
- do {
85
- let result = try await call ( data)
86
- await completion ( result, nil )
87
- } catch {
88
- await completion ( nil , error)
89
- }
90
- }
91
- } else {
92
- // This isn’t expected to ever be called because Functions
93
- // doesn’t officially support the older platforms.
94
- functions. callFunction (
95
- at: url,
96
- withObject: data,
97
- options: options,
98
- timeout: timeoutInterval
99
- ) { result in
100
- switch result {
101
- case let . success( callableResult) :
102
- DispatchQueue . main. async {
103
- completion ( callableResult, nil )
104
- }
105
- case let . failure( error) :
106
- DispatchQueue . main. async {
107
- completion ( nil , error)
108
- }
109
- }
110
- }
111
- }
78
+ sendableCallable. call ( data, completion: completion)
112
79
}
113
80
114
81
/// Executes this Callable HTTPS trigger asynchronously. This API should only be used from
@@ -124,8 +91,8 @@ open class HTTPSCallable: NSObject {
124
91
/// resumes with a new FCM Token the next time you call this method.
125
92
///
126
93
/// - Parameter completion: The block to call when the HTTPS request has completed.
127
- @objc ( callWithCompletion: ) public func __call( completion: @escaping ( HTTPSCallableResult ? ,
128
- Error ? ) -> Void ) {
94
+ @objc ( callWithCompletion: ) public func __call( completion: @escaping @ MainActor ( HTTPSCallableResult ? ,
95
+ Error ? ) -> Void ) {
129
96
call ( nil , completion: completion)
130
97
}
131
98
@@ -144,13 +111,94 @@ open class HTTPSCallable: NSObject {
144
111
/// - Throws: An error if the Cloud Functions invocation failed.
145
112
/// - Returns: The result of the call.
146
113
@available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
147
- open func call( _ data: Any ? = nil ) async throws -> HTTPSCallableResult {
148
- try await functions
149
- . callFunction ( at: url, withObject: data, options: options, timeout: timeoutInterval)
114
+ open func call( _ data: Any ? = nil ) async throws -> sending HTTPSCallableResult {
115
+ try await sendableCallable. call ( data)
150
116
}
151
117
152
118
@available ( macOS 12 . 0 , iOS 15 . 0 , watchOS 8 . 0 , tvOS 15 . 0 , * )
153
- func stream( _ data: Any ? = nil ) -> AsyncThrowingStream < JSONStreamResponse , Error > {
154
- functions. stream ( at: url, data: data, options: options, timeout: timeoutInterval)
119
+ func stream( _ data: SendableWrapper ? = nil ) -> AsyncThrowingStream < JSONStreamResponse , Error > {
120
+ sendableCallable. stream ( data)
121
+ }
122
+ }
123
+
124
+ private extension HTTPSCallable {
125
+ final class SendableHTTPSCallable : Sendable {
126
+ // MARK: - Private Properties
127
+
128
+ // The functions client to use for making calls.
129
+ private let functions : Functions
130
+
131
+ private let url : URL
132
+
133
+ private let options : HTTPSCallableOptions ?
134
+
135
+ // MARK: - Public Properties
136
+
137
+ let _timeoutInterval : AtomicBox < TimeInterval > = . init( 70 )
138
+
139
+ /// The timeout to use when calling the function. Defaults to 70 seconds.
140
+ var timeoutInterval : TimeInterval {
141
+ get { _timeoutInterval. value ( ) }
142
+ set {
143
+ _timeoutInterval. withLock { timeoutInterval in
144
+ timeoutInterval = newValue
145
+ }
146
+ }
147
+ }
148
+
149
+ init ( functions: Functions , url: URL , options: HTTPSCallableOptions ? = nil ) {
150
+ self . functions = functions
151
+ self . url = url
152
+ self . options = options
153
+ }
154
+
155
+ func call( _ data: sending Any? = nil ,
156
+ completion: @escaping @MainActor ( HTTPSCallableResult ? , Error ? ) -> Void ) {
157
+ if #available( iOS 13 , macCatalyst 13 , macOS 10 . 15 , tvOS 13 , watchOS 7 , * ) {
158
+ Task {
159
+ do {
160
+ let result = try await call ( data)
161
+ await completion ( result, nil )
162
+ } catch {
163
+ await completion ( nil , error)
164
+ }
165
+ }
166
+ } else {
167
+ // This isn’t expected to ever be called because Functions
168
+ // doesn’t officially support the older platforms.
169
+ functions. callFunction (
170
+ at: url,
171
+ withObject: data,
172
+ options: options,
173
+ timeout: timeoutInterval
174
+ ) { result in
175
+ switch result {
176
+ case let . success( callableResult) :
177
+ DispatchQueue . main. async {
178
+ completion ( callableResult, nil )
179
+ }
180
+ case let . failure( error) :
181
+ DispatchQueue . main. async {
182
+ completion ( nil , error)
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ func __call( completion: @escaping @MainActor ( HTTPSCallableResult ? , Error ? ) -> Void ) {
190
+ call ( nil , completion: completion)
191
+ }
192
+
193
+ @available ( iOS 13 , tvOS 13 , macOS 10 . 15 , macCatalyst 13 , watchOS 7 , * )
194
+ func call( _ data: Any ? = nil ) async throws -> sending HTTPSCallableResult {
195
+ try await functions
196
+ . callFunction ( at: url, withObject: data, options: options, timeout: timeoutInterval)
197
+ }
198
+
199
+ @available ( macOS 12 . 0 , iOS 15 . 0 , watchOS 8 . 0 , tvOS 15 . 0 , * )
200
+ func stream( _ data: SendableWrapper ? = nil ) -> AsyncThrowingStream < JSONStreamResponse , Error > {
201
+ functions. stream ( at: url, data: data, options: options, timeout: timeoutInterval)
202
+ }
155
203
}
156
204
}
0 commit comments