AuthUserDefaults.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright 2023 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. private let kPersistentDomainNamePrefix = "com.google.Firebase.Auth."
  16. // TODO: Remove this type after all tests and internal call sites are converted to Swift
  17. // This is added since a throwing function returning Optional values in Swift cannot be
  18. // exposed to Objective-C due to convention and meaning of nil values in Objective-C.
  19. // This wrapper allows us to always return a value, thus allowing us to expose Objective-C api.
  20. @objc(FIRDataWrapper) public class DataWrapper: NSObject {
  21. @objc public let data: Data?
  22. @objc public init(data: Data?) {
  23. self.data = data
  24. }
  25. }
  26. /**
  27. @brief The protocol for permanant data storage.
  28. */
  29. @objc(FIRAuthStorage) public protocol AuthStorage: NSObjectProtocol {
  30. // NOTE: Removing this from protocol since it's not being used anywhere.
  31. /** @fn initWithService:
  32. @brief Initialize a @c FIRAuthStorage instance.
  33. @param service The name of the storage service to use.
  34. @return An initialized @c FIRAuthStorage instance for the specified service.
  35. */
  36. // - (id<FIRAuthStorage>)initWithService:(NSString *)service;
  37. /** @fn dataForKey:error:
  38. @brief Gets the data for @c key in the storage. The key is set for the attribute
  39. @c kSecAttrAccount of a generic password query.
  40. @param key The key to use.
  41. @param error The address to store any error that occurs during the process, if not NULL.
  42. If the operation was successful, its content is set to @c nil .
  43. @return The data stored in the storage for @c key, if any.
  44. */
  45. @objc func data(forKey key: String) throws -> DataWrapper
  46. /** @fn setData:forKey:error:
  47. @brief Sets the data for @c key in the storage. The key is set for the attribute
  48. @c kSecAttrAccount of a generic password query.
  49. @param data The data to store.
  50. @param key The key to use.
  51. @param error The address to store any error that occurs during the process, if not NULL.
  52. @return Whether the operation succeeded or not.
  53. */
  54. @objc func setData(_ data: Data, forKey key: String) throws
  55. /** @fn removeDataForKey:error:
  56. @brief Removes the data for @c key in the storage. The key is set for the attribute
  57. @c kSecAttrAccount of a generic password query.
  58. @param key The key to use.
  59. @param error The address to store any error that occurs during the process, if not NULL.
  60. @return Whether the operation succeeded or not.
  61. */
  62. @objc func removeData(forKey key: String) throws
  63. }
  64. /** @class FIRAuthUserDefaults
  65. @brief The utility class to storage data in NSUserDefaults.
  66. */
  67. @objc(FIRAuthUserDefaults) public class AuthUserDefaults: NSObject, AuthStorage {
  68. /** @var _persistentDomainName
  69. @brief The name of the persistent domain in user defaults.
  70. */
  71. private let persistentDomainName: String
  72. /** @var _storage
  73. @brief The backing NSUserDefaults storage for this instance.
  74. */
  75. private let storage: UserDefaults
  76. @objc public required init(service: String) {
  77. persistentDomainName = kPersistentDomainNamePrefix + service
  78. storage = UserDefaults()
  79. }
  80. @objc public func data(forKey key: String) throws -> DataWrapper {
  81. guard let allData = storage.persistentDomain(forName: persistentDomainName)
  82. else { return DataWrapper(data: nil) }
  83. if let data = allData[key] as? Data {
  84. return DataWrapper(data: data)
  85. }
  86. return DataWrapper(data: nil)
  87. }
  88. @objc public func setData(_ data: Data, forKey key: String) throws {
  89. var allData = storage.persistentDomain(forName: persistentDomainName) ?? [:]
  90. allData[key] = data
  91. storage.setPersistentDomain(allData, forName: persistentDomainName)
  92. }
  93. @objc public func removeData(forKey key: String) throws {
  94. guard var allData = storage.persistentDomain(forName: persistentDomainName) else { return }
  95. allData.removeValue(forKey: key)
  96. storage.setPersistentDomain(allData, forName: persistentDomainName)
  97. }
  98. /** @fn clear
  99. @brief Clears all data from the storage.
  100. @remarks This method is only supposed to be called from tests.
  101. */
  102. @objc public func clear() {
  103. storage.setPersistentDomain([:], forName: persistentDomainName)
  104. }
  105. }