mirror of
https://github.com/home-assistant/iOS.git
synced 2026-02-05 06:35:37 -06:00
146 lines
4.8 KiB
Swift
146 lines
4.8 KiB
Swift
import Foundation
|
|
import GRDB
|
|
|
|
public struct ClientEvent: Codable, FetchableRecord, PersistableRecord {
|
|
public var id: String = UUID().uuidString
|
|
public var text: String = ""
|
|
public var type: EventType = .unknown
|
|
public var jsonPayload: [String: AnyCodable] = [:]
|
|
public var date: Date = Current.date()
|
|
|
|
public enum EventType: String, Codable, CaseIterable {
|
|
case notification
|
|
case serviceCall
|
|
case locationUpdate
|
|
case networkRequest
|
|
case settings
|
|
case database
|
|
case backgroundOperation
|
|
case unknown
|
|
}
|
|
|
|
public var jsonPayloadDescription: String? {
|
|
jsonData().flatMap { String(data: $0, encoding: .utf8) }
|
|
}
|
|
|
|
public init(
|
|
text: String,
|
|
type: EventType,
|
|
payload: [String: Any]? = [:],
|
|
date: Date = Current.date()
|
|
) {
|
|
self.text = text
|
|
self.type = type
|
|
self.jsonPayload = ClientEvent.convertToAnyCodable(payload ?? [:])
|
|
}
|
|
|
|
private func jsonData() -> Data? {
|
|
do {
|
|
let writeOptions: JSONSerialization.WritingOptions = [.prettyPrinted, .withoutEscapingSlashes]
|
|
return try JSONSerialization.data(withJSONObject: jsonPayloadJSONObject(), options: writeOptions)
|
|
} catch {
|
|
Current.Log.error("Error serializing json payload: \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
static func convertToAnyCodable(_ dictionary: [String: Any]) -> [String: AnyCodable] {
|
|
var newDictionary: [String: AnyCodable] = [:]
|
|
for (key, value) in dictionary {
|
|
if let value = value as? [String: Any] {
|
|
newDictionary[key] = AnyCodable(value)
|
|
} else {
|
|
newDictionary[key] = AnyCodable(value)
|
|
}
|
|
}
|
|
return newDictionary
|
|
}
|
|
|
|
public func jsonPayloadJSONObject() -> [String: Any] {
|
|
var newDictionary: [String: Any] = [:]
|
|
for (key, value) in jsonPayload {
|
|
newDictionary[key] = value.value
|
|
}
|
|
return newDictionary
|
|
}
|
|
}
|
|
|
|
public struct AnyCodable: Codable {
|
|
public let value: Any
|
|
|
|
public init(_ value: Any) {
|
|
self.value = value
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
if let bool = try? container.decode(Bool.self) {
|
|
self.value = bool
|
|
} else if let int = try? container.decode(Int.self) {
|
|
self.value = int
|
|
} else if let double = try? container.decode(Double.self) {
|
|
self.value = double
|
|
} else if let string = try? container.decode(String.self) {
|
|
self.value = string
|
|
} else if let array = try? container.decode([AnyCodable].self) {
|
|
self.value = array.map(\.value)
|
|
} else if let dictionary = try? container.decode([String: AnyCodable].self) {
|
|
self.value = dictionary.mapValues { $0.value }
|
|
} else {
|
|
throw DecodingError.dataCorruptedError(
|
|
in: container,
|
|
debugDescription: "AnyCodable value cannot be decoded"
|
|
)
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
switch value {
|
|
case let bool as Bool:
|
|
try container.encode(bool)
|
|
case let int as Int:
|
|
try container.encode(int)
|
|
case let double as Double:
|
|
try container.encode(double)
|
|
case let string as String:
|
|
try container.encode(string)
|
|
case let array as [Any]:
|
|
try container.encode(array.map(AnyCodable.init))
|
|
case let dictionary as [String: Any]:
|
|
try container.encode(dictionary.mapValues(AnyCodable.init))
|
|
default:
|
|
throw EncodingError.invalidValue(
|
|
value,
|
|
EncodingError.Context(
|
|
codingPath: container.codingPath,
|
|
debugDescription: "AnyCodable value cannot be encoded"
|
|
)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension ClientEvent.EventType {
|
|
var displayText: String {
|
|
switch self {
|
|
case .notification:
|
|
return L10n.ClientEvents.EventType.notification
|
|
case .locationUpdate:
|
|
return L10n.ClientEvents.EventType.locationUpdate
|
|
case .serviceCall:
|
|
return L10n.ClientEvents.EventType.serviceCall
|
|
case .networkRequest:
|
|
return L10n.ClientEvents.EventType.networkRequest
|
|
case .unknown:
|
|
return L10n.ClientEvents.EventType.unknown
|
|
case .settings:
|
|
return L10n.ClientEvents.EventType.settings
|
|
case .database:
|
|
return L10n.ClientEvents.EventType.database
|
|
case .backgroundOperation:
|
|
return L10n.ClientEvents.EventType.backgroundOperation
|
|
}
|
|
}
|
|
}
|