HTTPSCallable.swift 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // Copyright 2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import Foundation
  15. /**
  16. * A `HTTPSCallableResult` contains the result of calling a `HTTPSCallable`.
  17. */
  18. @objc(FIRHTTPSCallableResult)
  19. open class HTTPSCallableResult: NSObject {
  20. /**
  21. * The data that was returned from the Callable HTTPS trigger.
  22. *
  23. * The data is in the form of native objects. For example, if your trigger returned an
  24. * array, this object would be an `Array<Any>`. If your trigger returned a JavaScript object with
  25. * keys and values, this object would be an instance of `[String: Any]`.
  26. */
  27. @objc public let data: Any
  28. init(data: Any) {
  29. self.data = data
  30. }
  31. }
  32. /**
  33. * A `HTTPSCallable` is a reference to a particular Callable HTTPS trigger in Cloud Functions.
  34. */
  35. @objc(FIRHTTPSCallable)
  36. open class HTTPSCallable: NSObject {
  37. // MARK: - Private Properties
  38. // The functions client to use for making calls.
  39. private let functions: Functions
  40. private enum EndpointType {
  41. case name(String)
  42. case url(URL)
  43. }
  44. private let endpoint: EndpointType
  45. private let options: HTTPSCallableOptions?
  46. // MARK: - Public Properties
  47. /**
  48. * The timeout to use when calling the function. Defaults to 70 seconds.
  49. */
  50. @objc open var timeoutInterval: TimeInterval = 70
  51. init(functions: Functions, name: String, options: HTTPSCallableOptions? = nil) {
  52. self.functions = functions
  53. self.options = options
  54. endpoint = .name(name)
  55. }
  56. init(functions: Functions, url: URL, options: HTTPSCallableOptions? = nil) {
  57. self.functions = functions
  58. self.options = options
  59. endpoint = .url(url)
  60. }
  61. /**
  62. * Executes this Callable HTTPS trigger asynchronously.
  63. *
  64. * The data passed into the trigger can be any of the following types:
  65. * - `nil` or `NSNull`
  66. * - `String`
  67. * - `NSNumber`, or any Swift numeric type bridgeable to `NSNumber`
  68. * - `[Any]`, where the contained objects are also one of these types.
  69. * - `[String: Any]` where the values are also one of these types.
  70. *
  71. * The request to the Cloud Functions backend made by this method automatically includes a
  72. * Firebase Installations ID token to identify the app instance. If a user is logged in with
  73. * Firebase Auth, an auth ID token for the user is also automatically included.
  74. *
  75. * Firebase Cloud Messaging sends data to the Firebase backend periodically to collect information
  76. * regarding the app instance. To stop this, see `Messaging.deleteData()`. It
  77. * resumes with a new FCM Token the next time you call this method.
  78. *
  79. * - Parameters:
  80. * - data: Parameters to pass to the trigger.
  81. * - completion: The block to call when the HTTPS request has completed.
  82. */
  83. @objc(callWithObject:completion:) open func call(_ data: Any? = nil,
  84. completion: @escaping (HTTPSCallableResult?,
  85. Error?) -> Void) {
  86. let callback: ((Result<HTTPSCallableResult, Error>) -> Void) = { result in
  87. switch result {
  88. case let .success(callableResult):
  89. completion(callableResult, nil)
  90. case let .failure(error):
  91. completion(nil, error)
  92. }
  93. }
  94. switch endpoint {
  95. case let .name(name):
  96. functions.callFunction(name: name,
  97. withObject: data,
  98. options: options,
  99. timeout: timeoutInterval,
  100. completion: callback)
  101. case let .url(url):
  102. functions.callFunction(url: url,
  103. withObject: data,
  104. options: options,
  105. timeout: timeoutInterval,
  106. completion: callback)
  107. }
  108. }
  109. /**
  110. * Executes this Callable HTTPS trigger asynchronously. This API should only be used from Objective-C.
  111. *
  112. * The request to the Cloud Functions backend made by this method automatically includes a
  113. * Firebase Installations ID token to identify the app instance. If a user is logged in with
  114. * Firebase Auth, an auth ID token for the user is also automatically included.
  115. *
  116. * Firebase Cloud Messaging sends data to the Firebase backend periodically to collect information
  117. * regarding the app instance. To stop this, see `Messaging.deleteData()`. It
  118. * resumes with a new FCM Token the next time you call this method.
  119. *
  120. * - Parameter completion The block to call when the HTTPS request has completed.
  121. */
  122. @objc(callWithCompletion:) public func __call(completion: @escaping (HTTPSCallableResult?,
  123. Error?) -> Void) {
  124. call(nil, completion: completion)
  125. }
  126. #if compiler(>=5.5.2) && canImport(_Concurrency)
  127. /**
  128. * Executes this Callable HTTPS trigger asynchronously.
  129. *
  130. * The request to the Cloud Functions backend made by this method automatically includes a
  131. * FCM token to identify the app instance. If a user is logged in with Firebase
  132. * Auth, an auth ID token for the user is also automatically included.
  133. *
  134. * Firebase Cloud Messaging sends data to the Firebase backend periodically to collect information
  135. * regarding the app instance. To stop this, see `Messaging.deleteData()`. It
  136. * resumes with a new FCM Token the next time you call this method.
  137. *
  138. * - Parameter data Parameters to pass to the trigger.
  139. * - Throws: An error if the Cloud Functions invocation failed.
  140. * - Returns: The result of the call.
  141. */
  142. @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
  143. open func call(_ data: Any? = nil) async throws -> HTTPSCallableResult {
  144. return try await withCheckedThrowingContinuation { continuation in
  145. // TODO(bonus): Use task to handle and cancellation.
  146. self.call(data) { callableResult, error in
  147. if let callableResult = callableResult {
  148. continuation.resume(returning: callableResult)
  149. } else {
  150. continuation.resume(throwing: error!)
  151. }
  152. }
  153. }
  154. }
  155. #endif // compiler(>=5.5.2) && canImport(_Concurrency)
  156. }