added iOS source code
[wl-app.git] / iOS / Pods / MatomoTracker / MatomoTracker / URLSessionDispatcher.swift
1 import Foundation
2
3 #if os(OSX)
4     import WebKit
5 #elseif os(iOS)
6     import UIKit
7 #endif
8
9 final class URLSessionDispatcher: Dispatcher {
10     
11     let serializer = EventSerializer()
12     let timeout: TimeInterval
13     let session: URLSession
14     let baseURL: URL
15
16     private(set) var userAgent: String?
17     
18     /// Generate a URLSessionDispatcher instance
19     ///
20     /// - Parameters:
21     ///   - baseURL: The url of the Matomo server. This url has to end in `piwik.php`.
22     ///   - userAgent: An optional parameter for custom user agent.
23     init(baseURL: URL, userAgent: String? = nil) {                
24         self.baseURL = baseURL
25         self.timeout = 5
26         self.session = URLSession.shared
27         DispatchQueue.main.async {
28             self.userAgent = userAgent ?? URLSessionDispatcher.defaultUserAgent()
29         }
30     }
31     
32     private static func defaultUserAgent() -> String {
33         assertMainThread()
34         #if os(OSX)
35             let webView = WebView(frame: .zero)
36             let currentUserAgent = webView.stringByEvaluatingJavaScript(from: "navigator.userAgent") ?? ""
37         #elseif os(iOS)
38             let webView = UIWebView(frame: .zero)
39             var currentUserAgent = webView.stringByEvaluatingJavaScript(from: "navigator.userAgent") ?? ""
40             if let regex = try? NSRegularExpression(pattern: "\\((iPad|iPhone);", options: .caseInsensitive) {
41                 let deviceModel = Device.makeCurrentDevice().platform
42                 currentUserAgent = regex.stringByReplacingMatches(
43                     in: currentUserAgent,
44                     options: .withTransparentBounds,
45                     range: NSRange(location: 0, length: currentUserAgent.count),
46                     withTemplate: "(\(deviceModel);"
47                 )
48             }
49         #elseif os(tvOS)
50             let currentUserAgent = ""
51         #endif
52         return currentUserAgent.appending(" MatomoTracker SDK URLSessionDispatcher")
53     }
54     
55     func send(events: [Event], success: @escaping ()->(), failure: @escaping (_ error: Error)->()) {
56         let jsonBody: Data
57         do {
58             jsonBody = try serializer.jsonData(for: events)
59         } catch  {
60             failure(error)
61             return
62         }
63         let request = buildRequest(baseURL: baseURL, method: "POST", contentType: "application/json; charset=utf-8", body: jsonBody)
64         send(request: request, success: success, failure: failure)
65     }
66     
67     private func buildRequest(baseURL: URL, method: String, contentType: String? = nil, body: Data? = nil) -> URLRequest {
68         var request = URLRequest(url: baseURL, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: timeout)
69         request.httpMethod = method
70         body.map { request.httpBody = $0 }
71         contentType.map { request.setValue($0, forHTTPHeaderField: "Content-Type") }
72         userAgent.map { request.setValue($0, forHTTPHeaderField: "User-Agent") }
73         return request
74     }
75     
76     private func send(request: URLRequest, success: @escaping ()->(), failure: @escaping (_ error: Error)->()) {
77         let task = session.dataTask(with: request) { data, response, error in
78             // should we check the response?
79             // let dataString = String(data: data!, encoding: String.Encoding.utf8)
80             if let error = error {
81                 failure(error)
82             } else {
83                 success()
84             }
85         }
86         task.resume()
87     }
88     
89 }
90