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
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|