GuruAnalytics_iOS/GuruAnalytics/Classes/Internal/DataModel/Models.swift

229 lines
8.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//
// DBEntities.swift
// Alamofire
//
// Created by mayue on 2022/11/4.
//
import Foundation
import CryptoSwift
internal enum Entity {
}
extension Entity {
struct EventRecord: Codable {
enum Priority: Int, Codable {
case EMERGENCE = 0
case HIGH = 5
case DEFAULT = 10
case LOW = 15
}
enum TransitionStatus: Int, Codable {
case idle = 0
case instransition = 1
}
let recordId: String
let eventName: String
let eventJson: String
///
let timestamp: Int64
let priority: Priority
let transitionStatus: TransitionStatus
init(eventName: String, event: Entity.Event, priority: Priority = .DEFAULT, transitionStatus: TransitionStatus = .idle) {
let now = Date()
let eventJson = event.asString ?? ""
if eventJson.isEmpty {
cdPrint("[WARNING] error for convert event to json")
}
self.recordId = "\(eventName)\(eventJson)\(now.timeIntervalSince1970)\(Int.random(in: Int.min...Int.max))".md5()
self.eventName = eventName
self.eventJson = eventJson
self.timestamp = event.timestamp
self.priority = priority
self.transitionStatus = transitionStatus
}
init(recordId: String, eventName: String, eventJson: String, timestamp: Int64, priority: Int, transitionStatus: Int) {
self.recordId = recordId
self.eventName = eventName
self.eventJson = eventJson
self.timestamp = timestamp
self.priority = .init(rawValue: priority) ?? .DEFAULT
self.transitionStatus = .init(rawValue: transitionStatus) ?? .idle
}
enum CodingKeys: String, CodingKey {
case recordId
case eventName
case eventJson
case timestamp
case priority
case transitionStatus
}
static func createTableSql(with name: String) -> String {
return """
CREATE TABLE IF NOT EXISTS \(name)(
\(CodingKeys.recordId.rawValue) TEXT UNIQUE NOT NULL PRIMARY KEY,
\(CodingKeys.eventName.rawValue) TEXT NOT NULL,
\(CodingKeys.eventJson.rawValue) TEXT NOT NULL,
\(CodingKeys.timestamp.rawValue) INTEGER,
\(CodingKeys.priority.rawValue) INTEGER,
\(CodingKeys.transitionStatus.rawValue) INTEGER);
"""
}
func insertSql(to tableName: String) -> String {
return "INSERT INTO \(tableName) VALUES ('\(recordId)', '\(eventName)', '\(eventJson)', '\(timestamp)', '\(priority.rawValue)', '\(transitionStatus.rawValue)')"
}
}
}
extension Entity {
struct Event: Codable {
///
let timestamp: Int64
let event: String
let userInfo: UserInfo
let param: [String: EventValue]
let properties: [String: String]
let eventId: String
enum CodingKeys: String, CodingKey {
case timestamp
case userInfo = "info"
case event, param, properties
case eventId
}
init(timestamp: Int64, event: String, userInfo: UserInfo, parameters: [String : Any], properties: [String : String]) throws {
guard let normalizedEvent = Self.normalizeKey(event),
normalizedEvent == event else {
cdPrint("drop event because of illegal event name: \(event)")
cdPrint("standard: https://developers.google.com/android/reference/com/google/firebase/analytics/FirebaseAnalytics.Event")
throw NSError(domain: "cunstrcting event error", code: 0, userInfo: [NSLocalizedDescriptionKey : "illegal event name: \(event)"])
}
self.eventId = UUID().uuidString.lowercased()
self.timestamp = timestamp
self.event = normalizedEvent
self.userInfo = userInfo
self.param = Self.normalizeParameters(parameters)
self.properties = properties
}
static let maxParametersCount = 25
static let maxKeyLength = 40
static let maxParameterStringValueLength = 128
static func normalizeParameters(_ parameters: [String : Any]) -> [String : EventValue] {
var params = [String : EventValue]()
var count = 0
parameters.sorted(by: { $0.key < $1.key }).forEach({ key, value in
guard count < maxParametersCount else {
cdPrint("too many parameters")
cdPrint("standard: https://developers.google.com/android/reference/com/google/firebase/analytics/FirebaseAnalytics.Event")
return
}
guard let normalizedKey = normalizeKey(key),
normalizedKey == key else {
cdPrint("drop event parameter because of illegal key: \(key)")
cdPrint("standard: https://developers.google.com/android/reference/com/google/firebase/analytics/FirebaseAnalytics.Event")
return
}
if let value = value as? String {
params[normalizedKey] = Entity.EventValue(stringValue: String(value.prefix(maxParameterStringValueLength)))
} else if let value = value as? Int {
params[normalizedKey] = Entity.EventValue(longValue: Int64(value))
} else if let value = value as? Int64 {
params[normalizedKey] = Entity.EventValue(longValue: value)
} else if let value = value as? Double {
params[normalizedKey] = Entity.EventValue(doubleValue: value)
} else {
params[normalizedKey] = Entity.EventValue(stringValue: String("\(value)".prefix(maxParameterStringValueLength)))
}
count += 1
})
return params
}
static func normalizeKey(_ key: String) -> String? {
var mutableKey = key
while let first = mutableKey.first,
!first.isLetter {
_ = mutableKey.removeFirst()
}
var normalizedKey = ""
var count = 0
mutableKey.forEach { c in
guard count < maxKeyLength,
c.isAlphabetic || c.isDigit || c == "_" else { return }
normalizedKey.append(c)
count += 1
}
return normalizedKey.isEmpty ? nil : normalizedKey
}
}
///
struct UserInfo: Codable {
///IDuid
let uid: String?
///IDIDiOSIDFVUUIDAndroidandroidID
let deviceId: String?
///adjust_idadjust
let adjustId: String?
///广 ID/广 (IDFA)
let adId: String?
///pseudo_id
let firebaseId: String?
enum CodingKeys: String, CodingKey {
case deviceId
case uid
case adjustId
case adId
case firebaseId
}
}
//
struct EventValue: Codable {
let stringValue: String? //
let longValue: Int64? //
let doubleValue: Double? // APPJSON
init(stringValue: String? = nil, longValue: Int64? = nil, doubleValue: Double? = nil) {
self.stringValue = stringValue
self.longValue = longValue
self.doubleValue = doubleValue
}
enum CodingKeys: String, CodingKey {
case stringValue = "s"
case longValue = "i"
case doubleValue = "d"
}
}
}
extension Entity {
struct SystemTimeResult: Codable {
let data: Int64
}
}