Installations+InstallationsProtocol.swift 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. //
  2. // Copyright 2022 Google LLC
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. import Foundation
  16. internal import FirebaseInstallations
  17. internal import FirebaseCoreInternal
  18. protocol InstallationsProtocol: Sendable {
  19. var installationsWaitTimeInSecond: Int { get }
  20. /// Override Installation function for testing
  21. func authToken(completion: @escaping @Sendable (InstallationsAuthTokenResult?, Error?) -> Void)
  22. /// Override Installation function for testing
  23. func installationID(completion: @escaping @Sendable (String?, Error?) -> Void)
  24. /// Return a tuple: (installationID, authenticationToken) for success result
  25. func installationID(completion: @escaping (Result<(String, String), Error>) -> Void)
  26. }
  27. extension InstallationsProtocol {
  28. var installationsWaitTimeInSecond: Int {
  29. return 10
  30. }
  31. // TODO(ncooke3): Convert o async await ahead of Firebase 12.
  32. func installationID(completion: @escaping (Result<(String, String), Error>) -> Void) {
  33. let authTokenComplete = UnfairLock<String>("")
  34. let installationComplete = UnfairLock<String?>(nil)
  35. let errorComplete = UnfairLock<Error?>(nil)
  36. let workingGroup = DispatchGroup()
  37. workingGroup.enter()
  38. authToken { (authTokenResult: InstallationsAuthTokenResult?, error: Error?) in
  39. authTokenComplete.withLock { $0 = authTokenResult?.authToken ?? "" }
  40. workingGroup.leave()
  41. }
  42. workingGroup.enter()
  43. installationID { (installationID: String?, error: Error?) in
  44. if let installationID {
  45. installationComplete.withLock { $0 = installationID }
  46. } else if let error {
  47. errorComplete.withLock { $0 = error }
  48. }
  49. workingGroup.leave()
  50. }
  51. // adding timeout for 10 seconds
  52. let result = workingGroup
  53. .wait(timeout: .now() + DispatchTimeInterval.seconds(installationsWaitTimeInSecond))
  54. switch result {
  55. case .timedOut:
  56. completion(.failure(FirebaseSessionsError.SessionInstallationsTimeOutError))
  57. return
  58. default:
  59. if let installationComplete = installationComplete.value() {
  60. completion(.success((installationComplete, authTokenComplete.value())))
  61. } else if let errorComplete = errorComplete.value() {
  62. completion(.failure(errorComplete))
  63. }
  64. }
  65. }
  66. }
  67. extension Installations: InstallationsProtocol {}