added iOS source code
[wl-app.git] / iOS / Pods / MatomoTracker / MatomoTracker / URLSessionDispatcher.swift
diff --git a/iOS/Pods/MatomoTracker/MatomoTracker/URLSessionDispatcher.swift b/iOS/Pods/MatomoTracker/MatomoTracker/URLSessionDispatcher.swift
new file mode 100644 (file)
index 0000000..30fa473
--- /dev/null
@@ -0,0 +1,90 @@
+import Foundation
+
+#if os(OSX)
+    import WebKit
+#elseif os(iOS)
+    import UIKit
+#endif
+
+final class URLSessionDispatcher: Dispatcher {
+    
+    let serializer = EventSerializer()
+    let timeout: TimeInterval
+    let session: URLSession
+    let baseURL: URL
+
+    private(set) var userAgent: String?
+    
+    /// Generate a URLSessionDispatcher instance
+    ///
+    /// - Parameters:
+    ///   - baseURL: The url of the Matomo server. This url has to end in `piwik.php`.
+    ///   - userAgent: An optional parameter for custom user agent.
+    init(baseURL: URL, userAgent: String? = nil) {                
+        self.baseURL = baseURL
+        self.timeout = 5
+        self.session = URLSession.shared
+        DispatchQueue.main.async {
+            self.userAgent = userAgent ?? URLSessionDispatcher.defaultUserAgent()
+        }
+    }
+    
+    private static func defaultUserAgent() -> String {
+        assertMainThread()
+        #if os(OSX)
+            let webView = WebView(frame: .zero)
+            let currentUserAgent = webView.stringByEvaluatingJavaScript(from: "navigator.userAgent") ?? ""
+        #elseif os(iOS)
+            let webView = UIWebView(frame: .zero)
+            var currentUserAgent = webView.stringByEvaluatingJavaScript(from: "navigator.userAgent") ?? ""
+            if let regex = try? NSRegularExpression(pattern: "\\((iPad|iPhone);", options: .caseInsensitive) {
+                let deviceModel = Device.makeCurrentDevice().platform
+                currentUserAgent = regex.stringByReplacingMatches(
+                    in: currentUserAgent,
+                    options: .withTransparentBounds,
+                    range: NSRange(location: 0, length: currentUserAgent.count),
+                    withTemplate: "(\(deviceModel);"
+                )
+            }
+        #elseif os(tvOS)
+            let currentUserAgent = ""
+        #endif
+        return currentUserAgent.appending(" MatomoTracker SDK URLSessionDispatcher")
+    }
+    
+    func send(events: [Event], success: @escaping ()->(), failure: @escaping (_ error: Error)->()) {
+        let jsonBody: Data
+        do {
+            jsonBody = try serializer.jsonData(for: events)
+        } catch  {
+            failure(error)
+            return
+        }
+        let request = buildRequest(baseURL: baseURL, method: "POST", contentType: "application/json; charset=utf-8", body: jsonBody)
+        send(request: request, success: success, failure: failure)
+    }
+    
+    private func buildRequest(baseURL: URL, method: String, contentType: String? = nil, body: Data? = nil) -> URLRequest {
+        var request = URLRequest(url: baseURL, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: timeout)
+        request.httpMethod = method
+        body.map { request.httpBody = $0 }
+        contentType.map { request.setValue($0, forHTTPHeaderField: "Content-Type") }
+        userAgent.map { request.setValue($0, forHTTPHeaderField: "User-Agent") }
+        return request
+    }
+    
+    private func send(request: URLRequest, success: @escaping ()->(), failure: @escaping (_ error: Error)->()) {
+        let task = session.dataTask(with: request) { data, response, error in
+            // should we check the response?
+            // let dataString = String(data: data!, encoding: String.Encoding.utf8)
+            if let error = error {
+                failure(error)
+            } else {
+                success()
+            }
+        }
+        task.resume()
+    }
+    
+}
+