Personalization.swift 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright 2024 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. // TODO: AnalyticInterop refactor
  16. // import FirebaseAnalyticsInterop
  17. private let kAnalyticsOriginPersonalization = "fp"
  18. private let kExternalEvent = "personalization_assignment"
  19. private let kExternalRcParameterParam = "arm_key"
  20. private let kExternalArmValueParam = "arm_value"
  21. private let kPersonalizationId = "personalizationId"
  22. private let kExternalPersonalizationIdParam = "personalization_id"
  23. private let kArmIndex = "armIndex"
  24. private let kExternalArmIndexParam = "arm_index"
  25. private let kGroup = "group"
  26. private let kExternalGroupParam = "group"
  27. private let kInternalEvent = "_fpc"
  28. private let kChoiceId = "choiceId"
  29. private let kInternalChoiceIdParam = "_fpid"
  30. @objc(RCNPersonalization)
  31. public class Personalization: NSObject {
  32. /// Analytics connector.
  33. var analytics: FIRAnalyticsInterop?
  34. private var loggedChoiceIds = [String: String]()
  35. /// Designated initializer.
  36. @objc public init(analytics: FIRAnalyticsInterop?) {
  37. self.analytics = analytics
  38. super.init()
  39. }
  40. /// Called when an arm is pulled from Remote Config. If the arm is personalized, log information
  41. /// to
  42. /// Google Analytics in another thread.
  43. @objc public func logArmActive(rcParameter: String, config: [String: Any]) {
  44. guard let ids =
  45. config[ConfigConstants.fetchResponseKeyPersonalizationMetadata] as? [String: Any],
  46. let values = config[ConfigConstants.fetchResponseKeyEntries] as? [String: RemoteConfigValue],
  47. let value = values[rcParameter] else {
  48. return
  49. }
  50. guard let metadata = ids[rcParameter] as? [String: AnyHashable],
  51. let choiceId = metadata[kChoiceId] as? String else {
  52. return
  53. }
  54. // Listeners like logArmActive() are dispatched to a serial queue, so loggedChoiceIds should
  55. // contain any previously logged RC parameter / choice ID pairs.
  56. if loggedChoiceIds[rcParameter] == choiceId {
  57. return
  58. }
  59. loggedChoiceIds[rcParameter] = choiceId
  60. analytics?.logEvent(
  61. withOrigin: kAnalyticsOriginPersonalization,
  62. name: kExternalEvent,
  63. parameters: [
  64. kExternalRcParameterParam: rcParameter,
  65. kExternalArmValueParam: value.stringValue,
  66. kExternalPersonalizationIdParam: metadata[kPersonalizationId] ?? "",
  67. // Provide default value if nil
  68. kExternalArmIndexParam: metadata[kArmIndex] ?? "", // Provide default value if nil
  69. kExternalGroupParam: metadata[kGroup] ?? "", // Provide default value if nil
  70. ]
  71. )
  72. analytics?.logEvent(withOrigin: kAnalyticsOriginPersonalization,
  73. name: kInternalEvent,
  74. parameters: [kInternalChoiceIdParam: choiceId])
  75. }
  76. }