diff --git a/PianoAnalytics-AppExtension.podspec b/PianoAnalytics-AppExtension.podspec index 99e6da0..3dba4f0 100644 --- a/PianoAnalytics-AppExtension.podspec +++ b/PianoAnalytics-AppExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'PianoAnalytics-AppExtension' - s.version = '3.0.0' + s.version = '3.0.1' s.summary = 'Piano Analytics solution for extension Apple devices' s.homepage = 'https://github.com/at-internet/piano-analytics-apple' s.documentation_url = 'https://developers.atinternet-solutions.com/piano-analytics' diff --git a/PianoAnalytics.podspec b/PianoAnalytics.podspec index a5ab924..3ceff7b 100644 --- a/PianoAnalytics.podspec +++ b/PianoAnalytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'PianoAnalytics' - s.version = '3.0.0' + s.version = '3.0.1' s.summary = 'Piano Analytics library for Apple devices' s.homepage = 'https://github.com/at-internet/piano-analytics-apple' s.documentation_url = 'https://developers.atinternet-solutions.com/piano-analytics' diff --git a/Sources/PianoAnalytics/Core/UserDefaultKeys.swift b/Sources/PianoAnalytics/Core/UserDefaultKeys.swift index f377e4b..b3b0b6c 100644 --- a/Sources/PianoAnalytics/Core/UserDefaultKeys.swift +++ b/Sources/PianoAnalytics/Core/UserDefaultKeys.swift @@ -25,19 +25,61 @@ import Foundation +// MARK: Storage keys + enum PrivacyKeys: String, CaseIterable { + case PrivacyMode = "PAPrivacyMode" + case PrivacyModeExpirationTimestamp = "PAPrivacyModeExpirationTimestamp" + case PrivacyVisitorConsent = "PAPrivacyVisitorConsent" + case PrivacyVisitorId = "PAPrivacyUserId" +} + +enum VisitorIdKeys: String, CaseIterable { + case VisitorUUID = "PAApplicationUniqueIdentifier" + case VisitorUUIDGenerationTimestamp = "PAUserIdGenerationTimestamp" +} + +enum LifeCycleKeys: String, CaseIterable { + case FirstInitLifecycleDone = "PAFirstInitLifecycleDone" + case InitLifecycleDone = "PAInitLifecycleDone" + case FirstSession = "PAFirstLaunch" + case FirstSessionAfterUpdate = "PAFirstLaunchAfterUpdate" + case LastSessionDate = "PALastUse" + case FirstSessionDate = "PAFirstLaunchDate" + case SessionCount = "PALaunchCount" + case LastApplicationVersion = "PALastApplicationVersion" + case FirstSessionDateAfterUpdate = "PAApplicationUpdate" + case SessionCountSinceUpdate = "PALaunchCountSinceUpdate" + case DaysSinceFirstSession = "PADaysSinceFirstSession" + case DaysSinceUpdate = "PADaysSinceUpdate" + case DaysSinceLastSession = "PADaysSinceLastSession" +} + +enum CrashKeys: String, CaseIterable { + case Crashed = "PACrashed" + case CrashInfo = "PACrashInfo" +} + +enum UserKeys: String, CaseIterable { + case Users = "PAUsers" + case UserGenerationTimestamp = "PAUserGenerationTimestamp" +} + +// MARK: Old storage keys (v2 SDK retrocompatibility) + +enum ATPrivacyKeys: String { case PrivacyMode = "ATPrivacyMode" case PrivacyModeExpirationTimestamp = "ATPrivacyModeExpirationTimestamp" case PrivacyVisitorConsent = "ATPrivacyVisitorConsent" case PrivacyVisitorId = "ATPrivacyUserId" } -enum VisitorIdKeys: String, CaseIterable { +enum ATVisitorIdKeys: String, CaseIterable { case VisitorUUID = "ATApplicationUniqueIdentifier" case VisitorUUIDGenerationTimestamp = "ATUserIdGenerationTimestamp" } -enum LifeCycleKeys: String, CaseIterable { +enum ATLifeCycleKeys: String, CaseIterable { case FirstInitLifecycleDone = "ATFirstInitLifecycleDone" case InitLifecycleDone = "ATInitLifecycleDone" case FirstSession = "ATFirstLaunch" @@ -53,12 +95,11 @@ enum LifeCycleKeys: String, CaseIterable { case DaysSinceLastSession = "ATDaysSinceLastSession" } -enum CrashKeys: String, CaseIterable { +enum ATCrashKeys: String, CaseIterable { case Crashed = "ATCrashed" case CrashInfo = "ATCrashInfo" } -enum UserKeys: String, CaseIterable { +enum ATUserKeys: String, CaseIterable { case Users = "ATUsers" - case UserGenerationTimestamp = "PAUserGenerationTimestamp" } diff --git a/Sources/PianoAnalytics/Steps/CrashHandlingStep.swift b/Sources/PianoAnalytics/Steps/CrashHandlingStep.swift index ae52cb8..9dac673 100644 --- a/Sources/PianoAnalytics/Steps/CrashHandlingStep.swift +++ b/Sources/PianoAnalytics/Steps/CrashHandlingStep.swift @@ -47,6 +47,19 @@ final class CrashHandlingStep: Step { private final var isCrashHandlingRegistered: Bool = false private init(ps: PrivacyStep) { + let oldStorageKeyWithNew: [ATCrashKeys: CrashKeys] = [ + ATCrashKeys.Crashed: CrashKeys.Crashed, + ATCrashKeys.CrashInfo: CrashKeys.CrashInfo + ] + for (oldStorageKey, newStorageKey) in oldStorageKeyWithNew { + if (UserDefaults.standard.value(forKey: newStorageKey.rawValue) == nil) { + if let oldValue = UserDefaults.standard.value(forKey: oldStorageKey.rawValue) { + UserDefaults.standard.set(oldValue, forKey: newStorageKey.rawValue) + UserDefaults.standard.removeObject(forKey: oldStorageKey.rawValue) + } + } + } + self.privacyStep = ps self.exceptionHandler = { exception in let userDefaults = UserDefaults.standard diff --git a/Sources/PianoAnalytics/Steps/InternalContextPropertiesStep.swift b/Sources/PianoAnalytics/Steps/InternalContextPropertiesStep.swift index 1f52961..6df2f86 100644 --- a/Sources/PianoAnalytics/Steps/InternalContextPropertiesStep.swift +++ b/Sources/PianoAnalytics/Steps/InternalContextPropertiesStep.swift @@ -123,7 +123,7 @@ final class InternalContextPropertiesStep: Step { static let BrowserLanguagePropertiesFormat = "browser_language%@" private static let Manufacturer = "Apple" - private static let EventCollectionVersion = "3.0.0" + private static let EventCollectionVersion = "3.0.1" #if os(tvOS) private static let Platform = "tvOS" diff --git a/Sources/PianoAnalytics/Steps/LifecycleStep.swift b/Sources/PianoAnalytics/Steps/LifecycleStep.swift index 6648e68..35c8ec0 100644 --- a/Sources/PianoAnalytics/Steps/LifecycleStep.swift +++ b/Sources/PianoAnalytics/Steps/LifecycleStep.swift @@ -73,6 +73,30 @@ final class LifecycleStep: Step { private final var sessionBackgroundDuration: Int? private init(ps: PrivacyStep) { + let oldStorageKeyWithNew: [ATLifeCycleKeys: LifeCycleKeys] = [ + ATLifeCycleKeys.FirstInitLifecycleDone: LifeCycleKeys.FirstInitLifecycleDone, + ATLifeCycleKeys.InitLifecycleDone: LifeCycleKeys.InitLifecycleDone, + ATLifeCycleKeys.FirstSession: LifeCycleKeys.FirstSession, + ATLifeCycleKeys.FirstSessionAfterUpdate: LifeCycleKeys.FirstSessionAfterUpdate, + ATLifeCycleKeys.LastSessionDate: LifeCycleKeys.LastSessionDate, + ATLifeCycleKeys.FirstSessionDate: LifeCycleKeys.FirstSessionDate, + ATLifeCycleKeys.SessionCount: LifeCycleKeys.SessionCount, + ATLifeCycleKeys.LastApplicationVersion: LifeCycleKeys.LastApplicationVersion, + ATLifeCycleKeys.FirstSessionDateAfterUpdate: LifeCycleKeys.FirstSessionDateAfterUpdate, + ATLifeCycleKeys.SessionCountSinceUpdate: LifeCycleKeys.SessionCountSinceUpdate, + ATLifeCycleKeys.DaysSinceFirstSession: LifeCycleKeys.DaysSinceFirstSession, + ATLifeCycleKeys.DaysSinceUpdate: LifeCycleKeys.DaysSinceUpdate, + ATLifeCycleKeys.DaysSinceLastSession: LifeCycleKeys.DaysSinceLastSession + ] + for (oldStorageKey, newStorageKey) in oldStorageKeyWithNew { + if (UserDefaults.standard.value(forKey: newStorageKey.rawValue) == nil) { + if let oldValue = UserDefaults.standard.value(forKey: oldStorageKey.rawValue) { + UserDefaults.standard.set(oldValue, forKey: newStorageKey.rawValue) + UserDefaults.standard.removeObject(forKey: oldStorageKey.rawValue) + } + } + } + self.privacyStep = ps self.computingMetrics = [daysSinceFirstSession, daysSinceLastSession, daysSinceUpdate] let notificationCenter = NotificationCenter.default diff --git a/Sources/PianoAnalytics/Steps/PrivacyStep.swift b/Sources/PianoAnalytics/Steps/PrivacyStep.swift index 0d6e78d..c61f331 100644 --- a/Sources/PianoAnalytics/Steps/PrivacyStep.swift +++ b/Sources/PianoAnalytics/Steps/PrivacyStep.swift @@ -48,6 +48,21 @@ final class PrivacyStep: Step { private final let configurationStep: ConfigurationStep init(_ cs: ConfigurationStep) { + let oldStorageKeyWithNew: [ATPrivacyKeys: PrivacyKeys] = [ + ATPrivacyKeys.PrivacyMode: PrivacyKeys.PrivacyMode, + ATPrivacyKeys.PrivacyModeExpirationTimestamp: PrivacyKeys.PrivacyModeExpirationTimestamp, + ATPrivacyKeys.PrivacyVisitorConsent: PrivacyKeys.PrivacyVisitorConsent, + ATPrivacyKeys.PrivacyVisitorId: PrivacyKeys.PrivacyVisitorId + ] + for (oldStorageKey, newStorageKey) in oldStorageKeyWithNew { + if (UserDefaults.standard.value(forKey: newStorageKey.rawValue) == nil) { + if let oldValue = UserDefaults.standard.value(forKey: oldStorageKey.rawValue) { + UserDefaults.standard.set(oldValue, forKey: newStorageKey.rawValue) + UserDefaults.standard.removeObject(forKey: oldStorageKey.rawValue) + } + } + } + self.configurationStep = cs } diff --git a/Sources/PianoAnalytics/Steps/UsersStep.swift b/Sources/PianoAnalytics/Steps/UsersStep.swift index e43c4a9..4a27d3d 100644 --- a/Sources/PianoAnalytics/Steps/UsersStep.swift +++ b/Sources/PianoAnalytics/Steps/UsersStep.swift @@ -42,6 +42,14 @@ final class UsersStep: Step { private var userRecognition: Bool = false init(_ ps: PrivacyStep) { + if (UserDefaults.standard.value(forKey: UserKeys.Users.rawValue) == nil) { + if let oldValue = UserDefaults.standard.value(forKey: ATUserKeys.Users.rawValue) { + UserDefaults.standard.set(oldValue, forKey: UserKeys.Users.rawValue) + UserDefaults.standard.set(Int64(Date().timeIntervalSince1970) * 1000, forKey: UserKeys.UserGenerationTimestamp.rawValue) + UserDefaults.standard.removeObject(forKey: ATUserKeys.Users.rawValue) + } + } + self.privacyStep = ps } diff --git a/Sources/PianoAnalytics/Steps/VisitorIDStep.swift b/Sources/PianoAnalytics/Steps/VisitorIDStep.swift index 6cde9dd..5b86adf 100644 --- a/Sources/PianoAnalytics/Steps/VisitorIDStep.swift +++ b/Sources/PianoAnalytics/Steps/VisitorIDStep.swift @@ -120,6 +120,20 @@ final class VisitorIDStep: Step { private final let privacyStep: PrivacyStep private init(ps: PrivacyStep) { + let oldStorageKeyWithNew: [ATVisitorIdKeys: VisitorIdKeys] = [ + ATVisitorIdKeys.VisitorUUID: VisitorIdKeys.VisitorUUID, + ATVisitorIdKeys.VisitorUUIDGenerationTimestamp: VisitorIdKeys.VisitorUUIDGenerationTimestamp + ] + for (oldStorageKey, newStorageKey) in oldStorageKeyWithNew { + if (UserDefaults.standard.value(forKey: newStorageKey.rawValue) == nil) { + if let oldValue = UserDefaults.standard.value(forKey: oldStorageKey.rawValue) { + UserDefaults.standard.set(oldValue, forKey: newStorageKey.rawValue) + UserDefaults.standard.removeObject(forKey: oldStorageKey.rawValue) + } + } + } + + self.privacyStep = ps } diff --git a/Sources/PianoAnalytics/User.swift b/Sources/PianoAnalytics/User.swift index b39ca1c..2175f4a 100644 --- a/Sources/PianoAnalytics/User.swift +++ b/Sources/PianoAnalytics/User.swift @@ -44,13 +44,13 @@ public final class User { init(_ obj: [String: String]?) { self.id = obj?[User.Id] - self.category = obj?[User.Category] + self.category = obj?[User.Category] != "" ? obj?[User.Category] : nil } final func toString() -> String { guard let jsonData = PianoAnalyticsUtils.toJSONData([ User.Id: id, - User.Category: category + User.Category: category ?? "" ]) else { return "" }