@@ -29,29 +29,25 @@ open class HTTPSCallableResult: NSObject {
2929 }
3030}
3131
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.
3533@objc ( FIRHTTPSCallable)
36- open class HTTPSCallable : NSObject {
34+ open class HTTPSCallable : NSObject , @ unchecked Sendable {
3735 // MARK: - Private Properties
3836
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
4540
4641 // MARK: - Public Properties
4742
4843 /// 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+ }
5048
5149 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)
5551 }
5652
5753 /// Executes this Callable HTTPS trigger asynchronously.
@@ -79,36 +75,7 @@ open class HTTPSCallable: NSObject {
7975 completion: @escaping @MainActor ( HTTPSCallableResult ? ,
8076 Error ? )
8177 -> 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)
11279 }
11380
11481 /// Executes this Callable HTTPS trigger asynchronously. This API should only be used from
@@ -124,8 +91,8 @@ open class HTTPSCallable: NSObject {
12491 /// resumes with a new FCM Token the next time you call this method.
12592 ///
12693 /// - 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 ) {
12996 call ( nil , completion: completion)
13097 }
13198
@@ -144,13 +111,94 @@ open class HTTPSCallable: NSObject {
144111 /// - Throws: An error if the Cloud Functions invocation failed.
145112 /// - Returns: The result of the call.
146113 @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)
150116 }
151117
152118 @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+ }
155203 }
156204}
0 commit comments