Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom parameters can override existing parameters #397

Merged
merged 4 commits into from
Oct 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Changelog

## Unreleased
* **improvement** Allow overriding any of the tracking parameters. [#360](https://github.com/matomo-org/matomo-sdk-ios/issues/360)
* **improvement** Fixed build warnings
* **improvement** Use the new XCode build system
* **improvement** Use the new XCode build system [#391](https://github.com/matomo-org/matomo-sdk-ios/pull/391)
* **bugfix** Fixed issue where only `UserDefaults.standard` is used despite specified another instance. [#384](https://github.com/matomo-org/matomo-sdk-ios/pull/384)

## 7.4.0
Expand Down
52 changes: 28 additions & 24 deletions MatomoTracker.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,27 @@
1F38EBF81EE568D10021FBF8 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F38EBF71EE568D10021FBF8 /* Logger.swift */; };
1F3CA58C1E09A30600121FDC /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F3CA58B1E09A30600121FDC /* Queue.swift */; };
1F5927552178716E001478DC /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 1F5927542178716E001478DC /* CHANGELOG.md */; };
1F5D08721F5D79AD0064314F /* AutoTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F5D08711F5D79AD0064314F /* AutoTracker.swift */; };
1F6B2F032529CE8A00D2A591 /* UserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6B2F012529CC3400D2A591 /* UserAgent.swift */; };
1F6F0CD71E61E35A008170FC /* MatomoTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CD61E61E35A008170FC /* MatomoTracker.swift */; };
1F6F0CDC1E61E377008170FC /* DispatcherStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CD81E61E377008170FC /* DispatcherStub.swift */; };
1F6F0CDD1E61E377008170FC /* QueueStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CD91E61E377008170FC /* QueueStub.swift */; };
1F6F0CDE1E61E377008170FC /* TrackerFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CDA1E61E377008170FC /* TrackerFixtures.swift */; };
1F6F0CDC1E61E377008170FC /* DispatcherMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CD81E61E377008170FC /* DispatcherMock.swift */; };
1F6F0CDD1E61E377008170FC /* QueueMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CD91E61E377008170FC /* QueueMock.swift */; };
1F6F0CDF1E61E377008170FC /* TrackerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CDB1E61E377008170FC /* TrackerSpec.swift */; };
1F6F0CE11E61E4F3008170FC /* URLSessionDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F6F0CE01E61E4F3008170FC /* URLSessionDispatcher.swift */; };
1F7001CB216C9D8C007A9355 /* EventAPISerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7001CA216C9D8C007A9355 /* EventAPISerializer.swift */; };
1F7C667F1F8C096F0066CC64 /* MainThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F7C667E1F8C096F0066CC64 /* MainThread.swift */; };
1F80856F1E6B4B9800A61AAF /* Locale+HttpAcceptLanguage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F80856E1E6B4B9800A61AAF /* Locale+HttpAcceptLanguage.swift */; };
1F8DCCD425A1B9E100C98793 /* Event+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F8DCCD325A1B9E100C98793 /* Event+Fixture.swift */; };
1F8DCCD625A1BA2C00C98793 /* Visitor+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F8DCCD525A1BA2C00C98793 /* Visitor+Fixture.swift */; };
1F8DCCD825A1BA4900C98793 /* Session+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F8DCCD725A1BA4900C98793 /* Session+Fixture.swift */; };
1F8DCCDA25A1BAF700C98793 /* MatomoTracker+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F8DCCD925A1BAF700C98793 /* MatomoTracker+Fixture.swift */; };
1F8DCCDC25A1C7C700C98793 /* EventAPISerializerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F8DCCDB25A1C7C700C98793 /* EventAPISerializerSpec.swift */; };
1F963074201B37A3007B2AE7 /* PiwikUserDefaultsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F963073201B37A3007B2AE7 /* PiwikUserDefaultsSpec.swift */; };
1F963075201B37DC007B2AE7 /* MemoryQueueFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */; };
1FC2B429201F8C010061F5AD /* CustomVariable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FC2B428201F8C010061F5AD /* CustomVariable.swift */; };
1FCA6D451DBE0B2F0033F01C /* MatomoTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FCA6D3B1DBE0B2F0033F01C /* MatomoTracker.framework */; };
1FCA6D4C1DBE0B2F0033F01C /* MatomoTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCA6D3E1DBE0B2F0033F01C /* MatomoTracker.h */; settings = {ATTRIBUTES = (Public, ); }; };
1FCFF0241F82C7A50038BC17 /* CustomDimension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDC917B1F1A64BB0046F506 /* CustomDimension.swift */; };
1FDC917F1F1A65150046F506 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDC917D1F1A65150046F506 /* Application.swift */; };
1FDC91801F1A65150046F506 /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDC917E1F1A65150046F506 /* Device.swift */; };
240CC0A223269FFD003393F5 /* EventSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240CC0A123269FFD003393F5 /* EventSpec.swift */; };
5804E9A4755E642D58301330 /* Pods_MatomoTrackerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63DC1BA4812B98CA8037194A /* Pods_MatomoTrackerTests.framework */; };
5ACB1FAD21426FFB007C766B /* OrderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ACB1FAC21426FFB007C766B /* OrderItem.swift */; };
FDCA325A2093BFFB007D6B42 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = FDCA32592093BFFB007D6B42 /* README.md */; };
Expand All @@ -60,21 +61,23 @@
1F0A15CF1E6335E900FEAE72 /* Session.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Session.swift; sourceTree = "<group>"; };
1F1949F11E17A91100458199 /* MemoryQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryQueue.swift; sourceTree = "<group>"; };
1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryQueueSpec.swift; sourceTree = "<group>"; };
1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MemoryQueueFixtures.swift; path = Fixtures/MemoryQueueFixtures.swift; sourceTree = "<group>"; };
1F38EBF71EE568D10021FBF8 /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
1F3CA58B1E09A30600121FDC /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = "<group>"; };
1F5927542178716E001478DC /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
1F5D08711F5D79AD0064314F /* AutoTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoTracker.swift; sourceTree = "<group>"; };
1F6B2F012529CC3400D2A591 /* UserAgent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgent.swift; sourceTree = "<group>"; };
1F6F0CD61E61E35A008170FC /* MatomoTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatomoTracker.swift; sourceTree = "<group>"; };
1F6F0CD81E61E377008170FC /* DispatcherStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatcherStub.swift; sourceTree = "<group>"; };
1F6F0CD91E61E377008170FC /* QueueStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueStub.swift; sourceTree = "<group>"; };
1F6F0CDA1E61E377008170FC /* TrackerFixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackerFixtures.swift; sourceTree = "<group>"; };
1F6F0CD81E61E377008170FC /* DispatcherMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DispatcherMock.swift; sourceTree = "<group>"; };
1F6F0CD91E61E377008170FC /* QueueMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueueMock.swift; sourceTree = "<group>"; };
1F6F0CDB1E61E377008170FC /* TrackerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackerSpec.swift; sourceTree = "<group>"; };
1F6F0CE01E61E4F3008170FC /* URLSessionDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionDispatcher.swift; sourceTree = "<group>"; };
1F7001CA216C9D8C007A9355 /* EventAPISerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventAPISerializer.swift; sourceTree = "<group>"; };
1F7C667E1F8C096F0066CC64 /* MainThread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainThread.swift; sourceTree = "<group>"; };
1F80856E1E6B4B9800A61AAF /* Locale+HttpAcceptLanguage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Locale+HttpAcceptLanguage.swift"; sourceTree = "<group>"; };
1F8DCCD325A1B9E100C98793 /* Event+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Event+Fixture.swift"; sourceTree = "<group>"; };
1F8DCCD525A1BA2C00C98793 /* Visitor+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visitor+Fixture.swift"; sourceTree = "<group>"; };
1F8DCCD725A1BA4900C98793 /* Session+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Session+Fixture.swift"; sourceTree = "<group>"; };
1F8DCCD925A1BAF700C98793 /* MatomoTracker+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MatomoTracker+Fixture.swift"; sourceTree = "<group>"; };
1F8DCCDB25A1C7C700C98793 /* EventAPISerializerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventAPISerializerSpec.swift; sourceTree = "<group>"; };
1F963073201B37A3007B2AE7 /* PiwikUserDefaultsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PiwikUserDefaultsSpec.swift; sourceTree = "<group>"; };
1FC2B428201F8C010061F5AD /* CustomVariable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomVariable.swift; sourceTree = "<group>"; };
1FCA6D3B1DBE0B2F0033F01C /* MatomoTracker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MatomoTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand All @@ -85,7 +88,6 @@
1FDC917B1F1A64BB0046F506 /* CustomDimension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomDimension.swift; sourceTree = "<group>"; };
1FDC917D1F1A65150046F506 /* Application.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
1FDC917E1F1A65150046F506 /* Device.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Device.swift; sourceTree = "<group>"; };
240CC0A123269FFD003393F5 /* EventSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventSpec.swift; sourceTree = "<group>"; };
2FD38CC515C49A9A8922407D /* Pods-MatomoTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatomoTrackerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MatomoTrackerTests/Pods-MatomoTrackerTests.release.xcconfig"; sourceTree = "<group>"; };
5ACB1FAC21426FFB007C766B /* OrderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderItem.swift; sourceTree = "<group>"; };
63DC1BA4812B98CA8037194A /* Pods_MatomoTrackerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MatomoTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -132,18 +134,19 @@
1F1949F51E17B2A400458199 /* Fixtures */ = {
isa = PBXGroup;
children = (
1F6F0CDA1E61E377008170FC /* TrackerFixtures.swift */,
1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */,
1F8DCCD325A1B9E100C98793 /* Event+Fixture.swift */,
1F8DCCD525A1BA2C00C98793 /* Visitor+Fixture.swift */,
1F8DCCD725A1BA4900C98793 /* Session+Fixture.swift */,
1F8DCCD925A1BAF700C98793 /* MatomoTracker+Fixture.swift */,
);
name = Fixtures;
sourceTree = "<group>";
};
1F63E1D5216B503D000C4C00 /* Stubs */ = {
isa = PBXGroup;
children = (
1F6F0CD81E61E377008170FC /* DispatcherStub.swift */,
1F6F0CD91E61E377008170FC /* QueueStub.swift */,
1F5D08711F5D79AD0064314F /* AutoTracker.swift */,
1F6F0CD81E61E377008170FC /* DispatcherMock.swift */,
1F6F0CD91E61E377008170FC /* QueueMock.swift */,
);
name = Stubs;
sourceTree = "<group>";
Expand Down Expand Up @@ -208,8 +211,8 @@
1F1949F51E17B2A400458199 /* Fixtures */,
1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */,
1F6F0CDB1E61E377008170FC /* TrackerSpec.swift */,
240CC0A123269FFD003393F5 /* EventSpec.swift */,
1F963073201B37A3007B2AE7 /* PiwikUserDefaultsSpec.swift */,
1F8DCCDB25A1C7C700C98793 /* EventAPISerializerSpec.swift */,
1FCA6D4B1DBE0B2F0033F01C /* Info.plist */,
);
path = MatomoTrackerTests;
Expand Down Expand Up @@ -419,13 +422,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1F6F0CDD1E61E377008170FC /* QueueStub.swift in Sources */,
240CC0A223269FFD003393F5 /* EventSpec.swift in Sources */,
1F6F0CDC1E61E377008170FC /* DispatcherStub.swift in Sources */,
1F8DCCDC25A1C7C700C98793 /* EventAPISerializerSpec.swift in Sources */,
1F6F0CDD1E61E377008170FC /* QueueMock.swift in Sources */,
1F8DCCDA25A1BAF700C98793 /* MatomoTracker+Fixture.swift in Sources */,
1F6F0CDC1E61E377008170FC /* DispatcherMock.swift in Sources */,
1F963074201B37A3007B2AE7 /* PiwikUserDefaultsSpec.swift in Sources */,
1F963075201B37DC007B2AE7 /* MemoryQueueFixtures.swift in Sources */,
1F5D08721F5D79AD0064314F /* AutoTracker.swift in Sources */,
1F6F0CDE1E61E377008170FC /* TrackerFixtures.swift in Sources */,
1F8DCCD825A1BA4900C98793 /* Session+Fixture.swift in Sources */,
1F8DCCD625A1BA2C00C98793 /* Visitor+Fixture.swift in Sources */,
1F8DCCD425A1B9E100C98793 /* Event+Fixture.swift in Sources */,
1F1949F41E17B06600458199 /* MemoryQueueSpec.swift in Sources */,
1F6F0CDF1E61E377008170FC /* TrackerSpec.swift in Sources */,
);
Expand Down
51 changes: 24 additions & 27 deletions MatomoTracker/EventAPISerializer.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import Foundation

final class EventAPISerializer {
internal func queryItems(for event: Event) -> [String: String] {
event.queryItems.reduce(into: [String:String]()) {
$0[$1.name] = $1.value
}.compactMapValues {
$0.addingPercentEncoding(withAllowedCharacters: .urlQueryParameterAllowed)
}
}

internal func jsonData(for events: [Event]) throws -> Data {
let eventsAsQueryItems = events.map({ $0.queryItems })
let serializedEvents = eventsAsQueryItems.map({ items in
items.compactMap({ item in
guard let value = item.value,
let encodedValue = value.addingPercentEncoding(withAllowedCharacters: .urlQueryParameterAllowed) else { return nil }
return "\(item.name)=\(encodedValue)"
}).joined(separator: "&")
})
let eventsAsQueryItems: [[String: String]] = events.map { self.queryItems(for: $0) }
let serializedEvents = eventsAsQueryItems.map { items in
items.map {
"\($0.key)=\($0.value)"
}.joined(separator: "&")
}
let body = ["requests": serializedEvents.map({ "?\($0)" })]
return try JSONSerialization.data(withJSONObject: body, options: [])
}
Expand Down Expand Up @@ -94,14 +100,14 @@ fileprivate extension Event {
URLQueryItem(name: "ec_sh", value: orderShippingCost != nil ? "\(orderShippingCost!)" : nil),
URLQueryItem(name: "ec_dt", value: orderDiscount != nil ? "\(orderDiscount!)" : nil),
URLQueryItem(name: "_ects", value: lastOrderTimestamp),
].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) }
let customVariableItems = customVariables.count > 0 ? [URLQueryItem(name: "_cvar", value: customVariableParameterValue())] : []
let ecommerceOrderItemsAndFlag = orderItems.count > 0 ? [URLQueryItem(name: "ec_items", value: orderItemParameterValue()), URLQueryItem(name: "idgoal", value: "0")] : []

return items + dimensionItems + customItems + customVariableItems + ecommerceOrderItemsAndFlag
return items + dimensionItems + ecommerceOrderItemsAndFlag + customVariableItems + customItems
}
}
}
Expand All @@ -122,25 +128,16 @@ fileprivate extension DateFormatter {
dateFormatter.dateFormat = "ss"
return dateFormatter
}()
static let iso8601DateFormatter: DateFormatterProtocol = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return formatter
static let iso8601DateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(identifier: "UTC")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return formatter
}()
}

fileprivate protocol DateFormatterProtocol {
func string(from date: Date) -> String
func date(from string: String) -> Date?
}

@available(iOS 10, OSX 10.12, watchOS 3.0, tvOS 10.0, *)
extension ISO8601DateFormatter: DateFormatterProtocol {}
extension DateFormatter: DateFormatterProtocol {}

fileprivate extension CharacterSet {

/// Returns the character set for characters allowed in a query parameter URL component.
Expand Down
31 changes: 0 additions & 31 deletions MatomoTrackerTests/AutoTracker.swift

This file was deleted.

Loading