jsoncreator_app/JSONCreator_iOS/JSONCreator/5G/MFFGHSAnalyticsProtocol.swift

218 lines
7.6 KiB
Swift

//
// MFFGHSAnalyticsProtocol.swift
// MVM5G
//
// Created by Gujuluva Santharam, Ajai Prabhu on 20/05/20.
// Copyright © 2020 Kyle. All rights reserved.
//
import Foundation
import UIKit
import MVMCore
import MVMCoreUI
protocol MFFGHSAnalyticsProtocol {
func trackPage(data: [String: Any]?, additionalData: [String:Any]?)
func trackAction(action: [String: Any]?, pageData:[String: Any]?, additionalData: [String: Any]?)
func trackPageAppear(with pageJSON: [String: Any]?)
func trackPageDisappear(with pageJSON: [String: Any]?)
/** true means it will stop sending data to server when view appear to reduce data load. Temporary bool, will remove next release */
func stopInitialEvent() -> Bool
}
enum AnalyticsLogType: String {
case UI = "UI"
case BLE = "BLE"
}
struct AnalyticsPageInfo {
var pageType: String?
}
extension MFFGHSAnalyticsProtocol {
/** this boolean enable entire analytics feature. enable = false means nothing will send to server */
private var enable: Bool {
let initialParams:[String: Any] = [:]
return !initialParams.boolForKey("isFGAnalyticsDisabled")
}
/** enable time tracking feature. TODO - we are reducing call not sending data on start event. */
private var enableTimeTracker: Bool { return true }
/** true means it will stop sending data to server when view appear to reduce data load. Temporary bool, will remove next release */
func stopInitialEvent() -> Bool { return false }
func trackPage(data: [String: Any]?, additionalData:[String:Any]?) {
let params: [String: Any] = [
"eventType" : additionalData?["eventType"] ?? "pageDisplay",
"pageType" : data?["pageType"] ?? "NA",
"template" : data?["template"] ?? "NA",
"eventName" : additionalData?["eventName"] ?? "start",
"pageClass" : additionalData?["pageClass"] ?? String(describing: Self.self),
"epochSec" : Int(Date().timeIntervalSince1970),
"tdn" : getVendorId(),
"os" : "iOS"
]
let mergedParams = params.merging(additionalData ?? [:]) { $1 }
performRequest(params: ["data": mergedParams])
}
func trackAction(action: [String: Any]?, pageData:[String: Any]?, additionalData: [String: Any]?) {
/*
let params: [String: Any] = [
"eventType" : "action",
"actionPageType": action?["pageType"] ?? "NA",
"actionTitle" : action?["title"] ?? "NA",
"pageType" : pageData?.stringForkey("pageType") ?? "NA",
"template" : pageData?.stringForkey("template") ?? "NA",
"epochSec" : Int(Date().timeIntervalSince1970)
]
performRequest(params: params)
*/
}
func trackGemini(value: [String: Any], logType: AnalyticsLogType, pageInfo: AnalyticsPageInfo? = nil) {
var result: [String: Any] = [
"os" : "iOS",
"LogType" : logType.rawValue,
"tdn" : getVendorId()
]
if let pageInfo = pageInfo {
result["pageType"] = pageInfo.pageType
}
let payload = result.merging(value) { $1 }
performRequest(params: ["data": payload])
}
func trackPKI(processStep: String, attributeList: GMFGAnalyticsAttributeList?) {
var payload: [String: Any] = [
"processStep" : processStep,
"os" : "iOS",
"tdn" : getVendorId()
]
if let attributeList = attributeList {
payload["attributeList"] = attributeList.getList()
//GlassboxManager.glassboxCustomEvent(forKey: GMFGConstant.Glassbox.fivegSetup, withParameters: ["gen3Data": attributeList.getList()])
}
performRequest(params: payload, forPageType: "gen3Data")
}
func trackGen3Data(processStep: String, attributeList: GMFGAnalyticsAttributeList?) {
var payload: [String: Any] = [
"processStep" : processStep,
"os" : "iOS",
"tdn" : getVendorId()
]
if let attributeList = attributeList {
payload["attributeList"] = attributeList.getList()
}
performRequest(params: payload, forPageType: "gen3Data", priority: .high)
}
func resetGMAnalytics() {
LogRequestSerialiser.shared.resetTimer()
}
// MARK:- Get the Device UUID
func getVendorId() -> String {
let uuid = UIDevice.current.identifierForVendor?.uuidString
return uuid ?? GMFGConstant.empty
}
private func performRequest(params: [String: Any], forPageType: String = "logUIData", priority: LogPriority = .normal) {
if enable {
LogRequestSerialiser.shared.queueLogRequest(params: params, forPageType: forPageType, priority: priority)
}
}
// MARK:- Public API - Time Tracker
func trackPageAppear(with pageJSON: [String: Any]?) {
if !enableTimeTracker { return }
//GMFGSelfInstallTimeTracker.shared.trackPageAppear(with: pageJSON)
}
func trackPageDisappear(with pageJSON: [String: Any]?) {
if !enableTimeTracker { return }
//GMFGSelfInstallTimeTracker.shared.trackPageDisappear(with: pageJSON)
}
}
final class LogRequestSerialiser {
static let shared: LogRequestSerialiser = LogRequestSerialiser()
private lazy var requestQueue: [RequestItem] = []
private lazy var timer: Timer? = nil
private init() { /* this avoid creating new instance */ }
private var index = 0
fileprivate func queueLogRequest(params: [String: Any], forPageType: String, priority: LogPriority) {
let requestItem = RequestItem(priority: priority, endpoint: forPageType, parameters: params)
requestQueue.append(requestItem)
startTimer()
}
@objc fileprivate func performRequestIfAvailable() {
if requestQueue.count > index {
let objectToBePerformed = requestQueue[index]
if let reqParams = MVMCoreRequestParameters(pageType: objectToBePerformed.endpoint, extraParameters: nil) {
index = index + 1
reqParams.add(objectToBePerformed.parameters)
MVMCoreLoadHandler.sharedGlobal()?.loadBackgroundRequest(reqParams, dataForPage: nil, delegateObject: nil)
}
}
if requestQueue.count <= index { resetTimer() }
}
fileprivate func resetTimer() {
timer?.invalidate()
timer = nil
index = 0
requestQueue.removeAll()
}
fileprivate func startTimer() {
if timer == nil {
DispatchQueue.main.async {
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.performRequestIfAvailable), userInfo: nil, repeats: true)
self.timer?.tolerance = 0.5
}
}
}
}
fileprivate struct RequestItem {
var priority: LogPriority
var endpoint: String
var parameters: [String: Any]
}
fileprivate enum LogPriority {
case high
case normal
}
struct GMFGAnalyticsAttributeList {
private var attrList: [[String: Any]] = []
@available(*, deprecated, message: "use add(name:, value:)")
mutating func addAttribute(name: String, value: Any) {
attrList.append([
"attributeName": name,
"attributeValue": value
])
}
mutating func add(_ name: String, _ value: Any) {
attrList.append([
"attributeName": name,
"attributeValue": value
])
}
func getList() -> [[String: Any]] {
return attrList
}
}