117 lines
4.0 KiB
Swift
117 lines
4.0 KiB
Swift
//
|
||
// ProductConverter.swift
|
||
// StoreKit2Manager
|
||
//
|
||
// Created by xiaopin on 2025/12/6.
|
||
//
|
||
|
||
import Foundation
|
||
import StoreKit
|
||
|
||
/// Product 转换器
|
||
/// 将 Product 对象转换为可序列化的基础数据类型(Dictionary/JSON)
|
||
public struct ProductConverter {
|
||
|
||
/// 将 Product 转换为 Dictionary(可序列化为 JSON)
|
||
/// - Parameter product: Product 对象
|
||
/// - Returns: Dictionary 对象,包含所有产品信息
|
||
public static func toDictionary(_ product: Product) -> [String: Any] {
|
||
var dict: [String: Any] = [:]
|
||
|
||
// 基本信息(确保都是字符串类型)
|
||
dict["id"] = product.id
|
||
dict["displayName"] = product.displayName
|
||
dict["description"] = product.description
|
||
|
||
// 价格信息
|
||
let priceDecimal = product.price
|
||
let priceDouble = NSDecimalNumber(decimal: priceDecimal).doubleValue
|
||
dict["price"] = Double(String(format: "%.2f", priceDouble)) ?? priceDouble
|
||
dict["displayPrice"] = product.displayPrice
|
||
|
||
// 产品类型
|
||
dict["type"] = productTypeToString(product.type)
|
||
|
||
// 家庭共享
|
||
dict["isFamilyShareable"] = product.isFamilyShareable
|
||
|
||
// JSON 表示(可选,可能很大,通常用于服务器验证)
|
||
// 注意:jsonRepresentation 是 Data 类型,转换为 Base64 字符串以便 JSON 序列化
|
||
let jsonData = product.jsonRepresentation
|
||
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
||
dict["jsonRepresentation"] = jsonString
|
||
} else {
|
||
dict["jsonRepresentation"] = ""
|
||
}
|
||
|
||
// 订阅信息(如果有)
|
||
if let subscription = product.subscription {
|
||
dict["subscription"] = SubscriptionConverter.subscriptionInfoToDictionary(subscription, product: product)
|
||
} else {
|
||
dict["subscription"] = NSNull()
|
||
}
|
||
|
||
return dict
|
||
}
|
||
|
||
/// 将 Product 数组转换为 Dictionary 数组
|
||
/// - Parameter products: Product 数组
|
||
/// - Returns: Dictionary 数组
|
||
public static func toDictionaryArray(_ products: [Product]) -> [[String: Any]] {
|
||
return products.map { toDictionary($0) }
|
||
}
|
||
|
||
/// 将 Product 转换为 JSON 字符串
|
||
/// - Parameter product: Product 对象
|
||
/// - Returns: JSON 字符串
|
||
public static func toJSONString(_ product: Product) -> String? {
|
||
let dict = toDictionary(product)
|
||
return dictionaryToJSONString(dict)
|
||
}
|
||
|
||
/// 将 Product 数组转换为 JSON 字符串
|
||
/// - Parameter products: Product 数组
|
||
/// - Returns: JSON 字符串
|
||
public static func toJSONString(_ products: [Product]) -> String? {
|
||
let array = toDictionaryArray(products)
|
||
return arrayToJSONString(array)
|
||
}
|
||
|
||
// MARK: - 私有方法
|
||
|
||
/// 产品类型转字符串
|
||
private static func productTypeToString(_ type: Product.ProductType) -> String {
|
||
switch type {
|
||
case .consumable:
|
||
return "consumable"
|
||
case .nonConsumable:
|
||
return "nonConsumable"
|
||
case .autoRenewable:
|
||
return "autoRenewable"
|
||
case .nonRenewable:
|
||
return "nonRenewable"
|
||
default:
|
||
return "unknown"
|
||
}
|
||
}
|
||
|
||
/// Dictionary 转 JSON 字符串
|
||
internal static func dictionaryToJSONString(_ dict: [String: Any]) -> String? {
|
||
guard let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted),
|
||
let jsonString = String(data: jsonData, encoding: .utf8) else {
|
||
return nil
|
||
}
|
||
return jsonString
|
||
}
|
||
|
||
/// Array 转 JSON 字符串
|
||
internal static func arrayToJSONString(_ array: [[String: Any]]) -> String? {
|
||
guard let jsonData = try? JSONSerialization.data(withJSONObject: array, options: .prettyPrinted),
|
||
let jsonString = String(data: jsonData, encoding: .utf8) else {
|
||
return nil
|
||
}
|
||
return jsonString
|
||
}
|
||
}
|
||
|