Files
suixinkan_uikit/suixinkan/Core/Push/PushModels.swift

131 lines
4.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
///
enum PushDestination: Sendable, Equatable {
case payment
case orders
case verificationOrders
case task
case queue
case messageCenter
///
var requiresScenicContext: Bool {
switch self {
case .payment, .task, .queue:
true
case .orders, .verificationOrders, .messageCenter:
false
}
}
}
/// /APNs payload JSON
struct PushPayload: Sendable, Equatable {
private let values: [String: String]
/// userInfo
nonisolated init(userInfo: [AnyHashable: Any]) {
var flattened: [String: String] = [:]
Self.mergeDictionary(userInfo, into: &flattened)
values = flattened
}
/// payload Actor 使
nonisolated init(values: [String: String]) {
self.values = values
}
///
nonisolated var normalizedValues: [String: String] {
values
}
///
nonisolated var destination: PushDestination {
let type = value(for: "type")
let route = value(for: "route")
let uri = value(for: "uri")
let action = value(for: "action")
let merged = [route, uri, action].joined(separator: " ").lowercased()
if type == "1" || type == "6"
|| merged.contains("payment") || merged.contains("payment_qr")
|| merged.contains("收款") {
return .payment
}
if merged.contains("queue") || merged.contains("scenic-queue")
|| merged.contains("排队") || merged.contains("叫号") {
return .queue
}
if merged.contains("verification") || merged.contains("writeoff")
|| merged.contains("write_off") || merged.contains("核销") {
return .verificationOrders
}
if merged.contains("order") || merged.contains("订单") {
return .orders
}
if merged.contains("task") || merged.contains("任务") {
return .task
}
return .messageCenter
}
private nonisolated func value(for key: String) -> String {
values[key]?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
}
private nonisolated static func mergeDictionary(
_ dictionary: [AnyHashable: Any],
into result: inout [String: String]
) {
for (rawKey, value) in dictionary {
guard let key = rawKey as? String else { continue }
merge(value, key: key, into: &result)
}
}
private nonisolated static func merge(
_ value: Any,
key: String,
into result: inout [String: String]
) {
if let dictionary = value as? [String: Any] {
result[key] = stringValue(value)
mergeDictionary(dictionary, into: &result)
return
}
if let dictionary = value as? [AnyHashable: Any] {
result[key] = stringValue(value)
mergeDictionary(dictionary, into: &result)
return
}
let text = stringValue(value)
result[key] = text
guard Self.nestedJSONKeys.contains(key),
let data = text.data(using: .utf8),
let object = try? JSONSerialization.jsonObject(with: data)
else { return }
if let dictionary = object as? [String: Any] {
mergeDictionary(dictionary, into: &result)
}
}
private nonisolated static func stringValue(_ value: Any) -> String {
switch value {
case let string as String:
string
case let number as NSNumber:
number.stringValue
default:
String(describing: value)
}
}
private nonisolated static let nestedJSONKeys: Set<String> = [
"extras", "extra", "data", "JMessageExtra", "n_extras",
]
}