From 2598a096f2585ae5955c99885b1be4eb6a6823e6 Mon Sep 17 00:00:00 2001 From: Karsten Rohweder Date: Wed, 22 Nov 2017 09:55:03 +0100 Subject: [PATCH 1/5] PiwikTracker.isOptedOut property visible to objc --- PiwikTracker/PiwikTracker.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index 5ccf29f4..51a3d91e 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -9,7 +9,7 @@ final public class PiwikTracker: NSObject { /// Defines if the user opted out of tracking. When set to true, every event /// will be discarded immediately. This property is persisted between app launches. - public var isOptedOut: Bool { + @objc public var isOptedOut: Bool { get { return PiwikUserDefaults.standard.optOut } From 85996852db708e16e15347d40dfb811b22efcf93 Mon Sep 17 00:00:00 2001 From: Karsten Rohweder Date: Wed, 22 Nov 2017 17:17:28 +0100 Subject: [PATCH 2/5] custom variables added to Tracker and Event for per-visit and per-event scoping --- PiwikTracker/CustomVariable.swift | 17 +++++++++++ PiwikTracker/Event.swift | 6 ++-- PiwikTracker/PiwikTracker.swift | 39 +++++++++++++++++++++++++ PiwikTracker/URLSessionDispatcher.swift | 18 +++++++++--- 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 PiwikTracker/CustomVariable.swift diff --git a/PiwikTracker/CustomVariable.swift b/PiwikTracker/CustomVariable.swift new file mode 100644 index 00000000..5420310e --- /dev/null +++ b/PiwikTracker/CustomVariable.swift @@ -0,0 +1,17 @@ + +import Foundation + + +/// See Custom Variable documentation here: https://piwik.org/docs/custom-variables/ +public struct CustomVariable { + + /// The index of the variable. Must be > 0. When using default custom vars, indices 1-3 + /// are reserved. +// let index: Int + + /// The name of the variable. + let name: String + + /// The value of the variable. + let value: String +} diff --git a/PiwikTracker/Event.swift b/PiwikTracker/Event.swift index ec752f9a..2650b0c7 100644 --- a/PiwikTracker/Event.swift +++ b/PiwikTracker/Event.swift @@ -55,8 +55,9 @@ public struct Event { /// api-key: urlref let referer: URL? let screenResolution : CGSize = Device.makeCurrentDevice().screenSize + /// api-key: _cvar - //let customVariables: [CustomVariable] + let customVariables: [CustomVariable] /// Event tracking /// https://piwik.org/docs/event-tracking/ @@ -71,7 +72,7 @@ public struct Event { } extension Event { - public init(tracker: PiwikTracker, action: [String], url: URL? = nil, referer: URL? = nil, eventCategory: String? = nil, eventAction: String? = nil, eventName: String? = nil, eventValue: Float? = nil, customTrackingParameters: [String:String] = [:], dimensions: [CustomDimension] = []) { + public init(tracker: PiwikTracker, action: [String], url: URL? = nil, referer: URL? = nil, eventCategory: String? = nil, eventAction: String? = nil, eventName: String? = nil, eventValue: Float? = nil, customTrackingParameters: [String:String] = [:], dimensions: [CustomDimension] = [], variables: [CustomVariable] = []) { self.siteId = tracker.siteId self.uuid = NSUUID() self.visitor = tracker.visitor @@ -88,5 +89,6 @@ extension Event { self.eventValue = eventValue self.dimensions = tracker.dimensions + dimensions self.customTrackingParameters = customTrackingParameters + self.customVariables = tracker.customVariables + variables } } diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index 51a3d91e..e1e0ae0f 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -36,6 +36,8 @@ final public class PiwikTracker: NSObject { internal var dimensions: [CustomDimension] = [] + @objc public var useDefaultCustomVariables: Bool = false + private lazy var cvars: [CustomVariable] = getDefaultCVars() /// This logger is used to perform logging of all sorts of piwik related information. /// Per default it is a `DefaultLogger` with a `minLevel` of `LogLevel.warning`. You can @@ -293,6 +295,43 @@ extension PiwikTracker { } } + +extension PiwikTracker { + + internal func getDefaultCVars() -> [CustomVariable] { + let currentDevice = Device.makeCurrentDevice() + let app = Application.makeCurrentApplication() + + return [ + CustomVariable( name: "Platform", value: currentDevice.platform ), + CustomVariable( name: "OS version", value: currentDevice.osVersion ), + CustomVariable( name: "App version", value: app.bundleVersion ?? "unknown" ) + ] + } + + /// - Returns: A view on the Custom Variables. + var customVariables: ArraySlice { + let startIndex = useDefaultCustomVariables ? 0 : 3 + return cvars[startIndex...] + } + + /// Adds a new Custom Dimension. + /// + /// - Parameter name: The name of the new Custom Variable + /// - Parameter value: The value of the new Custom Variable + /// - Returns: The index of the new parameter. Note that indices start at 3 to accommodate the default Custom Variables. + @objc public func addCustomVariable(_ name: String, value: String) -> Int { + cvars.append(CustomVariable(name: name, value: value)) + return cvars.count + } + + @objc public func removeCustomVariableAtIndex(_ index: Int) { + assert(index >= 3 && index < cvars.count, "Index out of bounds") + cvars.remove(at: index) + } + +} + // Objective-c compatibility extension extension PiwikTracker { diff --git a/PiwikTracker/URLSessionDispatcher.swift b/PiwikTracker/URLSessionDispatcher.swift index 8c34a688..a22a78d6 100644 --- a/PiwikTracker/URLSessionDispatcher.swift +++ b/PiwikTracker/URLSessionDispatcher.swift @@ -94,9 +94,15 @@ final class URLSessionDispatcher: Dispatcher { } fileprivate extension Event { + + private func cvarParameterValue() -> String { + var cvars: Array = customVariables.enumerated().map { "\"\($0.offset + 1)\":[\"\($0.element.name)\",\"\($0.element.value)\"]" } + return "{\(cvars.joined(separator: ","))}" + } + var queryItems: [URLQueryItem] { get { - let items = [ + var items = [ URLQueryItem(name: "idsite", value: siteId), URLQueryItem(name: "rec", value: "1"), // Visitor @@ -128,9 +134,13 @@ fileprivate extension Event { ].filter { $0.value != nil } - let dimensionItems = dimensions.map { URLQueryItem(name: "dimension\($0.index)", value: $0.value) } - let customItems = customTrackingParameters.map { return URLQueryItem(name: $0.key, value: $0.value) } - return items + dimensionItems + customItems + items += dimensions.map { URLQueryItem(name: "dimension\($0.index)", value: $0.value) } + items += customTrackingParameters.map { return URLQueryItem(name: $0.key, value: $0.value) } + if customVariables.count > 0 { + items.append( URLQueryItem(name: "_cvar", value: cvarParameterValue()) ) + } + + return items } } } From ae68fc44a3c1802d95e4e8e6b8946ec2b0c056de Mon Sep 17 00:00:00 2001 From: Karsten Rohweder Date: Thu, 23 Nov 2017 08:16:05 +0100 Subject: [PATCH 3/5] CustomVariables code documentation --- PiwikTracker/PiwikTracker.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index e1e0ae0f..4ef8f116 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -315,16 +315,17 @@ extension PiwikTracker { return cvars[startIndex...] } - /// Adds a new Custom Dimension. + /// Adds a new Custom Variable. /// /// - Parameter name: The name of the new Custom Variable /// - Parameter value: The value of the new Custom Variable - /// - Returns: The index of the new parameter. Note that indices start at 3 to accommodate the default Custom Variables. - @objc public func addCustomVariable(_ name: String, value: String) -> Int { + /// - Returns: The index of the new parameter. Note that indices start at 3 to accommodate the default Custom Variables. Also note that when default Custom Variables are turned off, the returned index is offset by 3 to what is actually sent to the Piwik API. + @objc @discardableResult public func addCustomVariable(_ name: String, value: String) -> Int { cvars.append(CustomVariable(name: name, value: value)) return cvars.count } + /// Remove a previously set Custom Variable. Note that the default Custom Variables cannot be removed. @objc public func removeCustomVariableAtIndex(_ index: Int) { assert(index >= 3 && index < cvars.count, "Index out of bounds") cvars.remove(at: index) From 2bde923bfd50465f8c48bef80ff9849248a72076 Mon Sep 17 00:00:00 2001 From: Karsten Rohweder Date: Thu, 23 Nov 2017 13:19:11 +0100 Subject: [PATCH 4/5] Objective-C accessibility for Custom Dimensions, Code documentation. --- PiwikTracker/CustomVariable.swift | 5 ----- PiwikTracker/PiwikTracker.swift | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/PiwikTracker/CustomVariable.swift b/PiwikTracker/CustomVariable.swift index 5420310e..ead32560 100644 --- a/PiwikTracker/CustomVariable.swift +++ b/PiwikTracker/CustomVariable.swift @@ -4,11 +4,6 @@ import Foundation /// See Custom Variable documentation here: https://piwik.org/docs/custom-variables/ public struct CustomVariable { - - /// The index of the variable. Must be > 0. When using default custom vars, indices 1-3 - /// are reserved. -// let index: Int - /// The name of the variable. let name: String diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index 4ef8f116..fec959bf 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -283,12 +283,22 @@ extension PiwikTracker { dimensions.append(dimension) } + /// Set a permanent custom dimension by value and index. + /// + /// This is a convenience alternative to set(dimension:) and calls the exact same functionality. Also, it is accessible from Objective-C. + /// + /// - Parameter value: The value for the new Custom Dimension + /// - Parameter forIndex: The index of the new Custom Dimension + @objc public func setDimension(_ value: String, forIndex index: Int) { + set(dimension: CustomDimension( index: index, value: value )); + } + /// Removes a previously set custom dimension. /// /// Use this method to remove a dimension that was set using the `set(value: String, forDimension index: Int)` method. /// /// - Parameter index: The index of the dimension. - public func remove(dimensionAtIndex index: Int) { + @objc public func remove(dimensionAtIndex index: Int) { dimensions = dimensions.filter({ dimension in dimension.index != index }) @@ -303,7 +313,7 @@ extension PiwikTracker { let app = Application.makeCurrentApplication() return [ - CustomVariable( name: "Platform", value: currentDevice.platform ), + CustomVariable( name: "Platform", value: currentDevice.platform ), CustomVariable( name: "OS version", value: currentDevice.osVersion ), CustomVariable( name: "App version", value: app.bundleVersion ?? "unknown" ) ] @@ -326,6 +336,10 @@ extension PiwikTracker { } /// Remove a previously set Custom Variable. Note that the default Custom Variables cannot be removed. + /// + /// Note that, as with any array, the index of any succeeding Custom Variables is decremented by 1. + /// + /// - Parameter index: The index that was previously returned by addCustomVariable(). @objc public func removeCustomVariableAtIndex(_ index: Int) { assert(index >= 3 && index < cvars.count, "Index out of bounds") cvars.remove(at: index) From 0b9be92899ced75000581cdbc3e2f0c9ff99223b Mon Sep 17 00:00:00 2001 From: Karsten Rohweder Date: Wed, 10 Jan 2018 15:28:18 +0100 Subject: [PATCH 5/5] Objective-C accessibility for PiwikTracker.dispatchInterval --- PiwikTracker/PiwikTracker.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PiwikTracker/PiwikTracker.swift b/PiwikTracker/PiwikTracker.swift index fec959bf..b8caf242 100644 --- a/PiwikTracker/PiwikTracker.swift +++ b/PiwikTracker/PiwikTracker.swift @@ -141,7 +141,7 @@ final public class PiwikTracker: NSObject { // MARK: dispatch timer - public var dispatchInterval: TimeInterval = 30.0 { + @objc public var dispatchInterval: TimeInterval = 30.0 { didSet { startDispatchTimer() }