added iOS source code
[wl-app.git] / iOS / Pods / MatomoTracker / MatomoTracker / EventSerializer.swift
diff --git a/iOS/Pods/MatomoTracker/MatomoTracker/EventSerializer.swift b/iOS/Pods/MatomoTracker/MatomoTracker/EventSerializer.swift
new file mode 100644 (file)
index 0000000..afa3172
--- /dev/null
@@ -0,0 +1,111 @@
+//
+//  EventSerializer.swift
+//  PiwikTracker
+//
+//  Created by Cornelius Horstmann on 11.01.18.
+//  Copyright © 2018 PIWIK. All rights reserved.
+//
+
+import Foundation
+
+final class EventSerializer {
+    internal func jsonData(for events: [Event]) throws -> Data {
+        let eventsAsQueryItems = events.map({ $0.queryItems })
+        let serializedEvents = eventsAsQueryItems.map({ items in
+            items.flatMap({ item in
+                guard let value = item.value,
+                    let encodedValue = value.addingPercentEncoding(withAllowedCharacters: .urlQueryParameterAllowed) else { return nil }
+                return "\(item.name)=\(encodedValue)"
+            }).joined(separator: "&")
+        })
+        let body = ["requests": serializedEvents.map({ "?\($0)" })]
+        return try JSONSerialization.data(withJSONObject: body, options: [])
+    }
+}
+
+fileprivate extension Event {
+    
+    private func customVariableParameterValue() -> String {
+        let customVariableParameterValue: [String] = customVariables.map { "\"\($0.index)\":[\"\($0.name)\",\"\($0.value)\"]" }
+        return "{\(customVariableParameterValue.joined(separator: ","))}"
+    }
+
+    var queryItems: [URLQueryItem] {
+        get {
+            let items = [
+                URLQueryItem(name: "idsite", value: siteId),
+                URLQueryItem(name: "rec", value: "1"),
+                // Visitor
+                URLQueryItem(name: "_id", value: visitor.id),
+                URLQueryItem(name: "uid", value: visitor.userId),
+                
+                // Session
+                URLQueryItem(name: "_idvc", value: "\(session.sessionsCount)"),
+                URLQueryItem(name: "_viewts", value: "\(Int(session.lastVisit.timeIntervalSince1970))"),
+                URLQueryItem(name: "_idts", value: "\(Int(session.firstVisit.timeIntervalSince1970))"),
+                
+                URLQueryItem(name: "url", value:url?.absoluteString),
+                URLQueryItem(name: "action_name", value: actionName.joined(separator: "/")),
+                URLQueryItem(name: "lang", value: language),
+                URLQueryItem(name: "urlref", value: referer?.absoluteString),
+                URLQueryItem(name: "new_visit", value: isNewSession ? "1" : nil),
+                
+                URLQueryItem(name: "h", value: DateFormatter.hourDateFormatter.string(from: date)),
+                URLQueryItem(name: "m", value: DateFormatter.minuteDateFormatter.string(from: date)),
+                URLQueryItem(name: "s", value: DateFormatter.secondsDateFormatter.string(from: date)),
+                
+                //screen resolution
+                URLQueryItem(name: "res", value:String(format: "%1.0fx%1.0f", screenResolution.width, screenResolution.height)),
+                
+                URLQueryItem(name: "e_c", value: eventCategory),
+                URLQueryItem(name: "e_a", value: eventAction),
+                URLQueryItem(name: "e_n", value: eventName),
+                URLQueryItem(name: "e_v", value: eventValue != nil ? "\(eventValue!)" : nil),
+                
+                URLQueryItem(name: "_rcn", value: campaignName),
+                URLQueryItem(name: "_rck", value: campaignKeyword),
+
+                URLQueryItem(name: "search", value: searchQuery),
+                URLQueryItem(name: "search_cat", value: searchCategory),
+                URLQueryItem(name: "search_count", value: searchResultsCount != nil ? "\(searchResultsCount!)" : nil),
+                
+                URLQueryItem(name: "c_n", value: contentName),
+                URLQueryItem(name: "c_p", value: contentPiece),
+                URLQueryItem(name: "c_t", value: contentTarget),
+                URLQueryItem(name: "c_i", value: contentInteraction),
+                ].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())] : []
+
+            return items + dimensionItems + customItems + customVariableItems
+        }
+    }
+}
+
+fileprivate extension DateFormatter {
+    static let hourDateFormatter: DateFormatter = {
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "HH"
+        return dateFormatter
+    }()
+    static let minuteDateFormatter: DateFormatter = {
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "mm"
+        return dateFormatter
+    }()
+    static let secondsDateFormatter: DateFormatter = {
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "ss"
+        return dateFormatter
+    }()
+}
+
+fileprivate extension CharacterSet {
+    
+    /// Returns the character set for characters allowed in a query parameter URL component.
+    fileprivate static var urlQueryParameterAllowed: CharacterSet {
+        return CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "&/?"))
+    }
+}