--- /dev/null
+import Foundation
+
+/// MatomoUserDefaults is a wrapper for the UserDefaults with properties
+/// mapping onto values stored in the UserDefaults.
+/// All getter and setter are sideeffect free and automatically syncronize
+/// after writing.
+internal struct MatomoUserDefaults {
+ let userDefaults: UserDefaults
+
+ init(suiteName: String?) {
+ userDefaults = UserDefaults(suiteName: suiteName)!
+ }
+
+ var totalNumberOfVisits: Int {
+ get {
+ return userDefaults.integer(forKey: MatomoUserDefaults.Key.totalNumberOfVisits)
+ }
+ set {
+ userDefaults.set(newValue, forKey: MatomoUserDefaults.Key.totalNumberOfVisits)
+ userDefaults.synchronize()
+ }
+ }
+
+ var firstVisit: Date? {
+ get {
+ return userDefaults.object(forKey: MatomoUserDefaults.Key.firstVistsTimestamp) as? Date
+ }
+ set {
+ userDefaults.set(newValue, forKey: MatomoUserDefaults.Key.firstVistsTimestamp)
+ userDefaults.synchronize()
+ }
+ }
+
+ var previousVisit: Date? {
+ get {
+ return userDefaults.object(forKey: MatomoUserDefaults.Key.previousVistsTimestamp) as? Date
+ }
+ set {
+ userDefaults.set(newValue, forKey: MatomoUserDefaults.Key.previousVistsTimestamp)
+ userDefaults.synchronize()
+ }
+ }
+
+ var currentVisit: Date? {
+ get {
+ return userDefaults.object(forKey: MatomoUserDefaults.Key.currentVisitTimestamp) as? Date
+ }
+ set {
+ userDefaults.set(newValue, forKey: MatomoUserDefaults.Key.currentVisitTimestamp)
+ userDefaults.synchronize()
+ }
+ }
+
+ var optOut: Bool {
+ get {
+ return userDefaults.bool(forKey: MatomoUserDefaults.Key.optOut)
+ }
+ set {
+ userDefaults.set(newValue, forKey: MatomoUserDefaults.Key.optOut)
+ userDefaults.synchronize()
+ }
+ }
+
+ var clientId: String? {
+ get {
+ return userDefaults.string(forKey: MatomoUserDefaults.Key.clientID)
+ }
+ set {
+ userDefaults.setValue(newValue, forKey: MatomoUserDefaults.Key.clientID)
+ userDefaults.synchronize()
+ }
+ }
+
+ var visitorUserId: String? {
+ get {
+ return userDefaults.string(forKey: MatomoUserDefaults.Key.visitorUserID);
+ }
+ set {
+ userDefaults.setValue(newValue, forKey: MatomoUserDefaults.Key.visitorUserID);
+ userDefaults.synchronize()
+ }
+ }
+}
+
+extension MatomoUserDefaults {
+ public mutating func copy(from userDefaults: UserDefaults) {
+ totalNumberOfVisits = UserDefaults.standard.integer(forKey: MatomoUserDefaults.Key.totalNumberOfVisits)
+ firstVisit = UserDefaults.standard.object(forKey: MatomoUserDefaults.Key.firstVistsTimestamp) as? Date
+ previousVisit = UserDefaults.standard.object(forKey: MatomoUserDefaults.Key.previousVistsTimestamp) as? Date
+ currentVisit = UserDefaults.standard.object(forKey: MatomoUserDefaults.Key.currentVisitTimestamp) as? Date
+ optOut = UserDefaults.standard.bool(forKey: MatomoUserDefaults.Key.optOut)
+ clientId = UserDefaults.standard.string(forKey: MatomoUserDefaults.Key.clientID)
+ visitorUserId = UserDefaults.standard.string(forKey: MatomoUserDefaults.Key.visitorUserID)
+ }
+}
+
+extension MatomoUserDefaults {
+ internal struct Key {
+ static let totalNumberOfVisits = "PiwikTotalNumberOfVistsKey"
+ static let currentVisitTimestamp = "PiwikCurrentVisitTimestampKey"
+ static let previousVistsTimestamp = "PiwikPreviousVistsTimestampKey"
+ static let firstVistsTimestamp = "PiwikFirstVistsTimestampKey"
+
+ // Note: To be compatible with previous versions, the clientID key retains its old value,
+ // even though it is now a misnomer since adding visitorUserID makes it a bit confusing.
+ static let clientID = "PiwikVisitorIDKey"
+ static let visitorUserID = "PiwikVisitorUserIDKey"
+ static let optOut = "PiwikOptOutKey"
+ }
+}