Identifiers.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. import FirebaseInstallations
  17. let sessionIDUserDefaultsKey = "com.firebase.sessions.sessionID"
  18. let lastSessionIDUserDefaultsKey = "com.firebase.sessions.lastSessionID"
  19. protocol IdentifierProvider {
  20. var installationID: String {
  21. get
  22. }
  23. var sessionID: String {
  24. get
  25. }
  26. var lastSessionID: String {
  27. get
  28. }
  29. }
  30. ///
  31. /// Identifiers is responsible for:
  32. /// 1) Getting the Installation ID from Installations
  33. /// 2) Generating the Session ID
  34. /// 3) Persisting and reading the Session ID from the last session
  35. /// (Maybe) 4) Persisting, reading, and incrementing an increasing index
  36. ///
  37. class Identifiers: IdentifierProvider {
  38. private let installations: InstallationsProtocol
  39. private var uuid: UUID
  40. init(installations: InstallationsProtocol) {
  41. self.installations = installations
  42. uuid = UUID()
  43. }
  44. func generateNewSessionID() {
  45. uuid = UUID()
  46. let lastStoredSessionID = UserDefaults.standard.string(forKey: sessionIDUserDefaultsKey) ?? ""
  47. UserDefaults.standard.set(lastStoredSessionID, forKey: lastSessionIDUserDefaultsKey)
  48. let newSessionID = uuid.uuidString.replacingOccurrences(of: "-", with: "").lowercased()
  49. UserDefaults.standard.set(newSessionID, forKey: sessionIDUserDefaultsKey)
  50. }
  51. // This method must be run on a background thread due to how Firebase Installations
  52. // handles threading.
  53. var installationID: String {
  54. if Thread.isMainThread {
  55. Logger
  56. .logError(
  57. "Error: Identifiers.installationID getter must be called on a background thread. Using an empty ID"
  58. )
  59. return ""
  60. }
  61. var localInstallationID = ""
  62. let semaphore = DispatchSemaphore(value: 0)
  63. installations.installationID { result in
  64. switch result {
  65. case let .success(fiid):
  66. localInstallationID = fiid
  67. case let .failure(error):
  68. Logger
  69. .logError(
  70. "Error getting Firebase Installation ID: \(error). Using an empty ID"
  71. )
  72. }
  73. semaphore.signal()
  74. }
  75. switch semaphore.wait(timeout: DispatchTime.now() + 1.0) {
  76. case .success:
  77. break
  78. case .timedOut:
  79. Logger.logError("Error: took too long to get the Firebase Installation ID. Using an empty ID")
  80. }
  81. return localInstallationID
  82. }
  83. var sessionID: String {
  84. return UserDefaults.standard.string(forKey: sessionIDUserDefaultsKey) ?? ""
  85. }
  86. var lastSessionID: String {
  87. return UserDefaults.standard.string(forKey: lastSessionIDUserDefaultsKey) ?? ""
  88. }
  89. }