220 lines
10 KiB
Swift
220 lines
10 KiB
Swift
//
|
|
// YXTrackingSQLiteManager.swift
|
|
// YXTrackingSDK
|
|
//
|
|
// Created by 1234 on 2026/2/6.
|
|
//
|
|
|
|
import UIKit
|
|
import SQLite3
|
|
|
|
class YXTrackingSQLiteManager: NSObject {
|
|
|
|
// 添加跟踪数据到数据库
|
|
class func addTrackingData(data: EventRequestResult) {
|
|
// 创建数据库连接
|
|
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
|
let path = URL(fileURLWithPath: dbPath).appendingPathComponent("tracking.sqlite").path
|
|
var db: OpaquePointer? = nil
|
|
if sqlite3_open(path, &db) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite open failed!");
|
|
return
|
|
}
|
|
|
|
YXTracking.shared.success(message: "SDK sqlite open success!");
|
|
|
|
// 创建表
|
|
let createTableSQL = """
|
|
CREATE TABLE IF NOT EXISTS tracking_data (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
system_code TEXT,
|
|
event_type TEXT,
|
|
user_info BLOB,
|
|
client_type INT,
|
|
client_timestamp INT64,
|
|
timestamp TEXT,
|
|
device_info BLOB,
|
|
event_params BLOB,
|
|
custom_tags BLOB
|
|
)
|
|
"""
|
|
if sqlite3_exec(db, createTableSQL, nil, nil, nil) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite create table failed!");
|
|
return
|
|
}
|
|
|
|
YXTracking.shared.success(message: "SDK sqlite create table success!");
|
|
|
|
// 插入数据
|
|
let encoder = JSONEncoder()
|
|
let insertSQL = "INSERT INTO tracking_data (system_code, event_type, user_info, client_type, client_timestamp, timestamp, device_info, event_params, custom_tags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
var statement: OpaquePointer? = nil
|
|
if sqlite3_prepare_v2(db, insertSQL, -1, &statement, nil) == SQLITE_OK {
|
|
let system_code = data.system_code ?? ""
|
|
let event_type = data.eventType ?? ""
|
|
let user_info = (data.userInfo != nil) ? try! encoder.encode(data.userInfo) : nil
|
|
let client_type = data.clientType ?? 0
|
|
let client_timestamp = data.clientTimestamp ?? 0
|
|
let timestamp = data.timestamp ?? ""
|
|
let device_info = try! encoder.encode(data.deviceInfo)
|
|
let event_params = try! encoder.encode(data.eventParams)
|
|
let custom_tags = try! JSONSerialization.data(withJSONObject: data.customTags ?? [], options: [])
|
|
if sqlite3_bind_text(statement, 1, system_code, -1, nil) != SQLITE_OK || sqlite3_bind_text(statement, 2, event_type, -1, nil) != SQLITE_OK || ((data.userInfo != nil) ? (sqlite3_bind_blob(statement, 3, user_info! as CFTypeRef as? UnsafeRawPointer, Int32(user_info!.count), nil) != SQLITE_OK) : (sqlite3_bind_null(statement, 3) != SQLITE_OK)) || sqlite3_bind_int(statement, 4, client_type) != SQLITE_OK || sqlite3_bind_int64(statement, 5, client_timestamp) != SQLITE_OK || sqlite3_bind_text(statement, 6, timestamp, -1, nil) != SQLITE_OK || sqlite3_bind_blob(statement, 7, device_info as CFTypeRef as? UnsafeRawPointer, Int32(device_info.count), nil) != SQLITE_OK || sqlite3_bind_blob(statement, 8, event_params as CFTypeRef as? UnsafeRawPointer, Int32(event_params.count), nil) != SQLITE_OK || sqlite3_bind_blob(statement, 9, custom_tags as CFTypeRef as? UnsafeRawPointer, Int32(custom_tags.count), nil) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite bind parameter failed!");
|
|
return
|
|
} else if sqlite3_step(statement) != SQLITE_DONE {
|
|
YXTracking.shared.error(message: "SDK sqlite insert data failed!");
|
|
return
|
|
}
|
|
|
|
YXTracking.shared.success(message: "SDK sqlite bind parameter success!");
|
|
} else {
|
|
YXTracking.shared.error(message: "SDK sqlite preparing to insert data failed!");
|
|
return
|
|
}
|
|
|
|
YXTracking.shared.success(message: "SDK sqlite insert data success!");
|
|
|
|
// 关闭数据库连接
|
|
do {
|
|
sqlite3_close(db)
|
|
}
|
|
|
|
}
|
|
|
|
// 读取跟踪数据
|
|
class func readTrackingData() -> [EventRequestResult] {
|
|
var trackingData: [EventRequestResult] = []
|
|
// 创建数据库连接
|
|
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
|
let path = URL(fileURLWithPath: dbPath).appendingPathComponent("tracking.sqlite").path
|
|
var db: OpaquePointer? = nil
|
|
if sqlite3_open(path, &db) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite open failed!");
|
|
return trackingData
|
|
}
|
|
|
|
// 查询数据
|
|
let decoder = JSONDecoder()
|
|
let querySQL = "SELECT system_code, event_type, user_info, client_type, client_timestamp, timestamp, device_info, event_params, custom_tags FROM tracking_data"
|
|
var statement: OpaquePointer? = nil
|
|
if sqlite3_prepare_v2(db, querySQL, -1, &statement, nil) == SQLITE_OK {
|
|
while (sqlite3_step(statement) == SQLITE_ROW) {
|
|
// 获取数据并转换为EventRequestResult
|
|
let system_code = String(cString: sqlite3_column_text(statement, 1))
|
|
let event_type = String(cString: sqlite3_column_text(statement, 2))
|
|
var user_info = UserInfo(userId: nil, userName: nil, account: nil)
|
|
if sqlite3_column_type(statement, 3) != SQLITE_NULL {
|
|
if let user_info_blob = sqlite3_column_blob(statement, 3) {
|
|
let user_info_blob_length = sqlite3_column_bytes(statement, 3)
|
|
let data = Data(bytes: user_info_blob, count: Int(user_info_blob_length))
|
|
user_info = try! decoder.decode(UserInfo.self, from: data)
|
|
}
|
|
}
|
|
let client_type = sqlite3_column_int(statement, 4)
|
|
let client_timestamp = sqlite3_column_int64(statement, 5)
|
|
let timestamp = String(cString: sqlite3_column_text(statement, 6))
|
|
var device_info = DeviceInfo(os: nil, model: nil, screenResolution: nil)
|
|
if sqlite3_column_type(statement, 7) != SQLITE_NULL {
|
|
if let device_info_blob = sqlite3_column_blob(statement, 7) {
|
|
let device_info_blob_length = sqlite3_column_bytes(statement, 7)
|
|
let data = Data(bytes: device_info_blob, count: Int(device_info_blob_length))
|
|
device_info = try! decoder.decode(DeviceInfo.self, from: data)
|
|
}
|
|
}
|
|
var event_params = EventParams(page: nil, buttonId: nil, url: nil)
|
|
if sqlite3_column_type(statement, 8) != SQLITE_NULL {
|
|
if let event_params_blob = sqlite3_column_blob(statement, 8) {
|
|
let event_params_blob_length = sqlite3_column_bytes(statement, 8)
|
|
let data = Data(bytes: event_params_blob, count: Int(event_params_blob_length))
|
|
event_params = try! decoder.decode(EventParams.self, from: data)
|
|
}
|
|
}
|
|
var custom_tags = Array<String>()
|
|
if sqlite3_column_type(statement, 9) != SQLITE_NULL {
|
|
if let custom_tags_blob = sqlite3_column_blob(statement, 9) {
|
|
let custom_tags_blob_length = sqlite3_column_bytes(statement, 9)
|
|
let data = Data(bytes: custom_tags_blob, count: Int(custom_tags_blob_length))
|
|
custom_tags = try! decoder.decode([String].self, from: data)
|
|
}
|
|
}
|
|
|
|
let event = EventRequestResult(system_code: system_code,
|
|
eventType: event_type,
|
|
userInfo: user_info,
|
|
clientType: client_type,
|
|
clientTimestamp: client_timestamp,
|
|
timestamp: timestamp,
|
|
deviceInfo: device_info,
|
|
eventParams: event_params,
|
|
customTags: custom_tags)
|
|
trackingData.append(event)
|
|
}
|
|
sqlite3_finalize(statement)
|
|
} else {
|
|
YXTracking.shared.error(message: "SDK sqlite read data failed!");
|
|
}
|
|
|
|
// 关闭数据库连接
|
|
do {
|
|
sqlite3_close(db)
|
|
}
|
|
return trackingData
|
|
}
|
|
|
|
// 删除跟踪数据
|
|
class func deleteTrackingData() {
|
|
// 创建数据库连接
|
|
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
|
let path = URL(fileURLWithPath: dbPath).appendingPathComponent("tracking.sqlite").path
|
|
var db: OpaquePointer? = nil
|
|
if sqlite3_open(path, &db) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite open failed!");
|
|
return
|
|
}
|
|
|
|
// 删除数据
|
|
let deleteSQL = "DELETE FROM tracking_data"
|
|
if sqlite3_exec(db, deleteSQL, nil, nil, nil) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite delete data failed!");
|
|
}
|
|
|
|
// 关闭数据库连接
|
|
do {
|
|
sqlite3_close(db)
|
|
}
|
|
}
|
|
|
|
// 获取数据库缓存条数
|
|
class func getTrackingDataCount() -> Int {
|
|
// 创建数据库连接
|
|
let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
|
|
let path = URL(fileURLWithPath: dbPath).appendingPathComponent("tracking.sqlite").path
|
|
var db: OpaquePointer? = nil
|
|
if sqlite3_open(path, &db) != SQLITE_OK {
|
|
YXTracking.shared.error(message: "SDK sqlite open failed!");
|
|
return -1
|
|
}
|
|
|
|
// 查询数据
|
|
var dataCount = -1
|
|
let querySQL = "SELECT COUNT(*) FROM tracking_data"
|
|
var statement: OpaquePointer? = nil
|
|
if sqlite3_prepare_v2(db, querySQL, -1, &statement, nil) == SQLITE_OK {
|
|
sqlite3_step(statement)
|
|
dataCount = Int(sqlite3_column_int64(statement, 0))
|
|
sqlite3_finalize(statement)
|
|
} else {
|
|
YXTracking.shared.error(message: "SDK sqlite read data failed!");
|
|
}
|
|
|
|
// 关闭数据库连接
|
|
do {
|
|
sqlite3_close(db)
|
|
}
|
|
|
|
return dataCount
|
|
}
|
|
|
|
}
|