616 lines
21 KiB
Swift
616 lines
21 KiB
Swift
//
|
||
// ProfileModels.swift
|
||
// suixinkan
|
||
//
|
||
|
||
import Foundation
|
||
|
||
/// 用户资料响应实体,表示“我的”页面展示的账号基础信息。
|
||
struct UserInfoResponse: Decodable, Equatable {
|
||
let avatar: String
|
||
let realName: String
|
||
let phone: String
|
||
let nickname: String
|
||
let roleName: String
|
||
let status: Int
|
||
let statusName: String
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case avatar
|
||
case realName = "real_name"
|
||
case phone
|
||
case nickname
|
||
case roleName = "role_name"
|
||
case status
|
||
case statusName = "status_name"
|
||
}
|
||
|
||
init(
|
||
avatar: String = "",
|
||
realName: String = "",
|
||
phone: String = "",
|
||
nickname: String = "",
|
||
roleName: String = "",
|
||
status: Int = 0,
|
||
statusName: String = ""
|
||
) {
|
||
self.avatar = avatar
|
||
self.realName = realName
|
||
self.phone = phone
|
||
self.nickname = nickname
|
||
self.roleName = roleName
|
||
self.status = status
|
||
self.statusName = statusName
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
avatar = try container.decodeLossyString(forKey: .avatar)
|
||
realName = try container.decodeLossyString(forKey: .realName)
|
||
phone = try container.decodeLossyString(forKey: .phone)
|
||
nickname = try container.decodeLossyString(forKey: .nickname)
|
||
roleName = try container.decodeLossyString(forKey: .roleName)
|
||
status = try container.decodeLossyInt(forKey: .status) ?? 0
|
||
statusName = try container.decodeLossyString(forKey: .statusName)
|
||
}
|
||
}
|
||
|
||
/// 用户资料更新请求实体,表示昵称、密码和头像修改参数。
|
||
struct UpdateInfoRequest: Encodable {
|
||
let nickname: String?
|
||
let password: String?
|
||
let avatar: String?
|
||
}
|
||
|
||
/// 摄影师个人空间配置响应,对齐 Android `ProfileInfoResponse`。
|
||
struct PhotographerProfileInfoResponse: Decodable, Equatable {
|
||
let id: Int
|
||
let scenicId: Int
|
||
let photogUid: Int
|
||
let realName: String
|
||
let nickname: String
|
||
let avatar: String
|
||
let scenicCertification: [String]
|
||
let description: String
|
||
let attrLabel: [String]
|
||
let shootLabel: [String]
|
||
let cameraDevice: [String]
|
||
let businessStartTime: String
|
||
let businessEndTime: String
|
||
let holidayStartTime: String
|
||
let holidayEndTime: String
|
||
let businessRange: [Int]
|
||
let acceptOrderStatus: Int
|
||
let schedule: [String: [PhotographerSchedule]]
|
||
let virtualPhone: String
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case id
|
||
case scenicId = "scenic_id"
|
||
case photogUid = "photog_uid"
|
||
case realName = "real_name"
|
||
case nickname
|
||
case avatar
|
||
case scenicCertification = "scenic_certification"
|
||
case description
|
||
case attrLabel = "attr_label"
|
||
case shootLabel = "shoot_label"
|
||
case cameraDevice = "camera_device"
|
||
case businessStartTime = "business_start_time"
|
||
case businessEndTime = "business_end_time"
|
||
case holidayStartTime = "holiday_start_time"
|
||
case holidayEndTime = "holiday_end_time"
|
||
case businessRange = "business_range"
|
||
case acceptOrderStatus = "accept_order_status"
|
||
case schedule
|
||
case virtualPhone = "virtual_phone"
|
||
}
|
||
|
||
init(
|
||
id: Int = 0,
|
||
scenicId: Int = 0,
|
||
photogUid: Int = 0,
|
||
realName: String = "",
|
||
nickname: String = "",
|
||
avatar: String = "",
|
||
scenicCertification: [String] = [],
|
||
description: String = "",
|
||
attrLabel: [String] = [],
|
||
shootLabel: [String] = [],
|
||
cameraDevice: [String] = [],
|
||
businessStartTime: String = "",
|
||
businessEndTime: String = "",
|
||
holidayStartTime: String = "",
|
||
holidayEndTime: String = "",
|
||
businessRange: [Int] = [],
|
||
acceptOrderStatus: Int = 0,
|
||
schedule: [String: [PhotographerSchedule]] = [:],
|
||
virtualPhone: String = ""
|
||
) {
|
||
self.id = id
|
||
self.scenicId = scenicId
|
||
self.photogUid = photogUid
|
||
self.realName = realName
|
||
self.nickname = nickname
|
||
self.avatar = avatar
|
||
self.scenicCertification = scenicCertification
|
||
self.description = description
|
||
self.attrLabel = attrLabel
|
||
self.shootLabel = shootLabel
|
||
self.cameraDevice = cameraDevice
|
||
self.businessStartTime = businessStartTime
|
||
self.businessEndTime = businessEndTime
|
||
self.holidayStartTime = holidayStartTime
|
||
self.holidayEndTime = holidayEndTime
|
||
self.businessRange = businessRange
|
||
self.acceptOrderStatus = acceptOrderStatus
|
||
self.schedule = schedule
|
||
self.virtualPhone = virtualPhone
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
id = try container.decodeLossyInt(forKey: .id) ?? 0
|
||
scenicId = try container.decodeLossyInt(forKey: .scenicId) ?? 0
|
||
photogUid = try container.decodeLossyInt(forKey: .photogUid) ?? 0
|
||
realName = try container.decodeLossyString(forKey: .realName)
|
||
nickname = try container.decodeLossyString(forKey: .nickname)
|
||
avatar = try container.decodeLossyString(forKey: .avatar)
|
||
scenicCertification = try container.decodeLossyStringArray(forKey: .scenicCertification)
|
||
description = try container.decodeLossyString(forKey: .description)
|
||
attrLabel = try container.decodeLossyStringArray(forKey: .attrLabel)
|
||
shootLabel = try container.decodeLossyStringArray(forKey: .shootLabel)
|
||
cameraDevice = try container.decodeLossyStringArray(forKey: .cameraDevice)
|
||
businessStartTime = try container.decodeLossyString(forKey: .businessStartTime)
|
||
businessEndTime = try container.decodeLossyString(forKey: .businessEndTime)
|
||
holidayStartTime = try container.decodeLossyString(forKey: .holidayStartTime)
|
||
holidayEndTime = try container.decodeLossyString(forKey: .holidayEndTime)
|
||
businessRange = try container.decodeLossyIntArray(forKey: .businessRange)
|
||
acceptOrderStatus = try container.decodeLossyInt(forKey: .acceptOrderStatus) ?? 0
|
||
schedule = try container.decodeIfPresent([String: [PhotographerSchedule]].self, forKey: .schedule) ?? [:]
|
||
virtualPhone = try container.decodeLossyString(forKey: .virtualPhone)
|
||
}
|
||
}
|
||
|
||
/// 摄影师日程实体,对齐 Android `ScheduleEntity`。
|
||
struct PhotographerSchedule: Decodable, Equatable, Hashable, Sendable {
|
||
let id: Int
|
||
let name: String
|
||
let remark: String
|
||
let startTime: String
|
||
let endTime: String
|
||
let scheduleDate: String
|
||
let orderNumber: String?
|
||
let userNickname: String?
|
||
let userPhone: String?
|
||
let orderStatus: Int?
|
||
let orderStatusName: String?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case id
|
||
case name
|
||
case remark
|
||
case startTime = "start_time"
|
||
case endTime = "end_time"
|
||
case scheduleDate = "schedule_date"
|
||
case orderNumber = "order_number"
|
||
case userNickname = "user_nickname"
|
||
case userPhone = "user_phone"
|
||
case orderStatus = "order_status"
|
||
case orderStatusName = "order_status_name"
|
||
}
|
||
|
||
init(
|
||
id: Int = 0,
|
||
name: String = "",
|
||
remark: String = "",
|
||
startTime: String = "",
|
||
endTime: String = "",
|
||
scheduleDate: String = "",
|
||
orderNumber: String? = nil,
|
||
userNickname: String? = nil,
|
||
userPhone: String? = nil,
|
||
orderStatus: Int? = nil,
|
||
orderStatusName: String? = nil
|
||
) {
|
||
self.id = id
|
||
self.name = name
|
||
self.remark = remark
|
||
self.startTime = startTime
|
||
self.endTime = endTime
|
||
self.scheduleDate = scheduleDate
|
||
self.orderNumber = orderNumber
|
||
self.userNickname = userNickname
|
||
self.userPhone = userPhone
|
||
self.orderStatus = orderStatus
|
||
self.orderStatusName = orderStatusName
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
id = try container.decodeLossyInt(forKey: .id) ?? 0
|
||
name = try container.decodeLossyString(forKey: .name)
|
||
remark = try container.decodeLossyString(forKey: .remark)
|
||
startTime = try container.decodeLossyString(forKey: .startTime)
|
||
endTime = try container.decodeLossyString(forKey: .endTime)
|
||
scheduleDate = try container.decodeLossyString(forKey: .scheduleDate)
|
||
orderNumber = try container.decodeIfPresent(String.self, forKey: .orderNumber)
|
||
userNickname = try container.decodeIfPresent(String.self, forKey: .userNickname)
|
||
userPhone = try container.decodeIfPresent(String.self, forKey: .userPhone)
|
||
orderStatus = try container.decodeLossyInt(forKey: .orderStatus)
|
||
orderStatusName = try container.decodeIfPresent(String.self, forKey: .orderStatusName)
|
||
}
|
||
}
|
||
|
||
/// 摄影师个人空间配置更新请求,对齐 Android `UpdateProfileInfoRequest`。
|
||
struct UpdatePhotographerProfileInfoRequest: Encodable, Equatable {
|
||
let scenicId: String
|
||
let description: String
|
||
let cameraDevice: [String]
|
||
let attrLabel: [String]
|
||
let shootLabel: [String]
|
||
let businessStartTime: String
|
||
let businessEndTime: String
|
||
let holidayStartTime: String
|
||
let holidayEndTime: String
|
||
let businessRange: [Int]
|
||
let acceptOrderStatus: Int
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case scenicId = "scenic_id"
|
||
case description
|
||
case cameraDevice = "camera_device"
|
||
case attrLabel = "attr_label"
|
||
case shootLabel = "shoot_label"
|
||
case businessStartTime = "business_start_time"
|
||
case businessEndTime = "business_end_time"
|
||
case holidayStartTime = "holiday_start_time"
|
||
case holidayEndTime = "holiday_end_time"
|
||
case businessRange = "business_range"
|
||
case acceptOrderStatus = "accept_order_status"
|
||
}
|
||
}
|
||
|
||
/// 摄影师新增日程请求,对齐 Android `AddScheduleRequest`。
|
||
struct AddPhotographerScheduleRequest: Encodable, Equatable {
|
||
var scenicId: String
|
||
var name: String
|
||
var remark: String
|
||
var startTime: String
|
||
var endTime: String
|
||
var scheduleDate: String
|
||
var orderNumber: String?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case scenicId = "scenic_id"
|
||
case name
|
||
case remark
|
||
case startTime = "start_time"
|
||
case endTime = "end_time"
|
||
case scheduleDate = "schedule_date"
|
||
case orderNumber = "order_number"
|
||
}
|
||
}
|
||
|
||
/// 摄影师删除日程请求,对齐 Android `ScheduleDeleteRequest`。
|
||
struct PhotographerScheduleDeleteRequest: Encodable, Equatable {
|
||
let id: Int
|
||
}
|
||
|
||
/// 实名认证响应实体,包裹当前用户的认证详情。
|
||
struct RealNameInfoResponse: Decodable, Equatable {
|
||
let realNameInfo: RealNameInfo?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case realNameInfo = "real_name_info"
|
||
}
|
||
}
|
||
|
||
/// 实名认证信息实体,表示当前用户实名审核状态和失败原因。
|
||
struct RealNameInfo: Decodable, Equatable {
|
||
let realName: String
|
||
let idCardNo: String
|
||
let auditStatus: Int
|
||
let auditStatusText: String?
|
||
let rejectReason: String?
|
||
let startDate: String?
|
||
let endDate: String?
|
||
let isLongValid: Bool
|
||
let frontUrl: String?
|
||
let backUrl: String?
|
||
let auditorId: Int?
|
||
let auditor: RealNameAuditor?
|
||
let auditAt: String?
|
||
|
||
var verified: Bool {
|
||
auditStatus == 2
|
||
}
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case realName = "real_name"
|
||
case idCardNo = "id_card_no"
|
||
case auditStatus = "audit_status"
|
||
case auditStatusText = "audit_status_text"
|
||
case rejectReason = "reject_reason"
|
||
case startDate = "start_date"
|
||
case endDate = "end_date"
|
||
case isLongValid = "is_long_valid"
|
||
case frontUrl = "front_url"
|
||
case backUrl = "back_url"
|
||
case auditorId = "auditor_id"
|
||
case auditor
|
||
case auditAt = "audit_at"
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
realName = try container.decodeLossyString(forKey: .realName)
|
||
idCardNo = try container.decodeLossyString(forKey: .idCardNo)
|
||
auditStatus = try container.decodeLossyInt(forKey: .auditStatus) ?? 0
|
||
auditStatusText = try container.decodeIfPresent(String.self, forKey: .auditStatusText)
|
||
rejectReason = try container.decodeIfPresent(String.self, forKey: .rejectReason)
|
||
startDate = try container.decodeIfPresent(String.self, forKey: .startDate)
|
||
endDate = try container.decodeIfPresent(String.self, forKey: .endDate)
|
||
isLongValid = (try container.decodeLossyInt(forKey: .isLongValid) ?? 0) == 1
|
||
frontUrl = try container.decodeIfPresent(String.self, forKey: .frontUrl)
|
||
backUrl = try container.decodeIfPresent(String.self, forKey: .backUrl)
|
||
auditorId = try container.decodeLossyInt(forKey: .auditorId)
|
||
auditor = try container.decodeIfPresent(RealNameAuditor.self, forKey: .auditor)
|
||
auditAt = try container.decodeIfPresent(String.self, forKey: .auditAt)
|
||
}
|
||
}
|
||
|
||
/// 实名认证审核人实体,表示后台审核人的基础展示信息。
|
||
struct RealNameAuditor: Decodable, Equatable {
|
||
let id: Int
|
||
let name: String
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case id
|
||
case name
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
id = try container.decodeLossyInt(forKey: .id) ?? 0
|
||
name = try container.decodeLossyString(forKey: .name)
|
||
}
|
||
}
|
||
|
||
/// 实名认证提交请求实体,表示用户填写的姓名、证件号、短信和证件图片。
|
||
struct RealNameAuthRequest: Encodable, Equatable {
|
||
let realName: String
|
||
let idCardNo: String
|
||
let smsVerifyCode: String
|
||
let startDate: String
|
||
let endDate: String
|
||
let isLongValid: Int
|
||
let frontUrl: String
|
||
let backUrl: String
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case realName = "real_name"
|
||
case idCardNo = "id_card_no"
|
||
case smsVerifyCode = "sms_verify_code"
|
||
case startDate = "start_date"
|
||
case endDate = "end_date"
|
||
case isLongValid = "is_long_valid"
|
||
case frontUrl = "front_url"
|
||
case backUrl = "back_url"
|
||
}
|
||
}
|
||
|
||
/// 银行卡信息响应实体。
|
||
struct BankCardInfoResponse: Decodable, Equatable {
|
||
let bankCard: BankCardInfo?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case bankCard = "bank_card"
|
||
}
|
||
}
|
||
|
||
/// 银行卡信息实体,表示提现设置与审核状态。
|
||
struct BankCardInfo: Decodable, Equatable {
|
||
let realName: String
|
||
let bankName: String
|
||
let branchName: String
|
||
let cardNumber: String
|
||
let frontUrl: String?
|
||
let backUrl: String?
|
||
let provinceCode: String?
|
||
let cityCode: String?
|
||
let rejectReason: String
|
||
let auditStatus: Int
|
||
let auditStatusLabel: String
|
||
let auditAt: String?
|
||
let auditorId: Int?
|
||
let auditor: RealNameAuditor?
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case realName = "real_name"
|
||
case bankName = "bank_name"
|
||
case branchName = "branch_name"
|
||
case cardNumber = "card_number"
|
||
case frontUrl = "front_url"
|
||
case backUrl = "back_url"
|
||
case provinceCode = "province_code"
|
||
case cityCode = "city_code"
|
||
case rejectReason = "reject_reason"
|
||
case auditStatus = "audit_status"
|
||
case auditStatusLabel = "audit_status_label"
|
||
case auditAt = "audit_at"
|
||
case auditorId = "auditor_id"
|
||
case auditor
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
realName = try container.decodeLossyString(forKey: .realName)
|
||
bankName = try container.decodeLossyString(forKey: .bankName)
|
||
branchName = try container.decodeLossyString(forKey: .branchName)
|
||
cardNumber = try container.decodeLossyString(forKey: .cardNumber)
|
||
frontUrl = try container.decodeIfPresent(String.self, forKey: .frontUrl)
|
||
backUrl = try container.decodeIfPresent(String.self, forKey: .backUrl)
|
||
provinceCode = try container.decodeIfPresent(String.self, forKey: .provinceCode)
|
||
cityCode = try container.decodeIfPresent(String.self, forKey: .cityCode)
|
||
rejectReason = try container.decodeLossyString(forKey: .rejectReason)
|
||
auditStatus = try container.decodeLossyInt(forKey: .auditStatus) ?? 0
|
||
auditStatusLabel = try container.decodeLossyString(forKey: .auditStatusLabel)
|
||
auditAt = try container.decodeIfPresent(String.self, forKey: .auditAt)
|
||
auditorId = try container.decodeLossyInt(forKey: .auditorId)
|
||
auditor = try container.decodeIfPresent(RealNameAuditor.self, forKey: .auditor)
|
||
}
|
||
}
|
||
|
||
/// 银行列表响应实体。
|
||
struct BankListResponse: Decodable, Equatable {
|
||
let banks: [String]
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case banks
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
banks = try container.decodeIfPresent([String].self, forKey: .banks) ?? []
|
||
}
|
||
}
|
||
|
||
/// 省市区响应实体。
|
||
struct AreasResponse: Decodable, Equatable, Identifiable {
|
||
let id: Int
|
||
let code: String
|
||
let name: String
|
||
let children: [AreasResponse]
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case id
|
||
case code
|
||
case name
|
||
case children
|
||
}
|
||
|
||
init(from decoder: Decoder) throws {
|
||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||
id = try container.decodeLossyInt(forKey: .id)
|
||
?? container.decodeLossyInt(forKey: .code)
|
||
?? 0
|
||
let decodedCode = try container.decodeLossyString(forKey: .code)
|
||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||
code = decodedCode.isEmpty ? "\(id)" : decodedCode
|
||
name = try container.decodeLossyString(forKey: .name)
|
||
children = try container.decodeIfPresent([AreasResponse].self, forKey: .children) ?? []
|
||
}
|
||
|
||
init(id: Int, code: String, name: String, children: [AreasResponse] = []) {
|
||
self.id = id
|
||
self.code = code
|
||
self.name = name
|
||
self.children = children
|
||
}
|
||
}
|
||
|
||
/// 更新银行卡信息请求实体。
|
||
struct UpdateBankInfoRequest: Encodable, Equatable {
|
||
let realName: String
|
||
let cardNumber: String
|
||
let bankName: String
|
||
let branchName: String
|
||
let frontUrl: String
|
||
let backUrl: String
|
||
let provinceCode: String
|
||
let cityCode: String
|
||
let smsVerifyCode: String
|
||
|
||
enum CodingKeys: String, CodingKey {
|
||
case realName = "real_name"
|
||
case cardNumber = "card_number"
|
||
case bankName = "bank_name"
|
||
case branchName = "branch_name"
|
||
case frontUrl = "front_url"
|
||
case backUrl = "back_url"
|
||
case provinceCode = "province_code"
|
||
case cityCode = "city_code"
|
||
case smsVerifyCode = "sms_verify_code"
|
||
}
|
||
}
|
||
|
||
/// 个人信息页校验错误实体。
|
||
enum ProfileValidationError: LocalizedError, Equatable {
|
||
case emptyNickname
|
||
case shortPassword
|
||
|
||
var errorDescription: String? {
|
||
switch self {
|
||
case .emptyNickname:
|
||
"请输入昵称"
|
||
case .shortPassword:
|
||
"密码至少 6 位"
|
||
}
|
||
}
|
||
}
|
||
|
||
private extension KeyedDecodingContainer {
|
||
func decodeLossyString(forKey key: Key) throws -> String {
|
||
if let value = try? decodeIfPresent(String.self, forKey: key) {
|
||
return value
|
||
}
|
||
if let value = try? decodeIfPresent(Int.self, forKey: key) {
|
||
return String(value)
|
||
}
|
||
if let value = try? decodeIfPresent(Double.self, forKey: key) {
|
||
return String(value)
|
||
}
|
||
if let value = try? decodeIfPresent(Bool.self, forKey: key) {
|
||
return value ? "true" : "false"
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func decodeLossyInt(forKey key: Key) throws -> Int? {
|
||
if let value = try? decodeIfPresent(Int.self, forKey: key) {
|
||
return value
|
||
}
|
||
if let value = try? decodeIfPresent(String.self, forKey: key) {
|
||
let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
|
||
if let intValue = Int(text) {
|
||
return intValue
|
||
}
|
||
if let doubleValue = Double(text) {
|
||
return Int(doubleValue)
|
||
}
|
||
}
|
||
if let value = try? decodeIfPresent(Double.self, forKey: key) {
|
||
return Int(value)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func decodeLossyStringArray(forKey key: Key) throws -> [String] {
|
||
if let values = try? decodeIfPresent([String].self, forKey: key) {
|
||
return values
|
||
}
|
||
if let values = try? decodeIfPresent([Int].self, forKey: key) {
|
||
return values.map(String.init)
|
||
}
|
||
if let value = try? decodeIfPresent(String.self, forKey: key) {
|
||
let text = value.trimmingCharacters(in: .whitespacesAndNewlines)
|
||
return text.isEmpty ? [] : [text]
|
||
}
|
||
return []
|
||
}
|
||
|
||
func decodeLossyIntArray(forKey key: Key) throws -> [Int] {
|
||
if let values = try? decodeIfPresent([Int].self, forKey: key) {
|
||
return values
|
||
}
|
||
if let values = try? decodeIfPresent([String].self, forKey: key) {
|
||
return values.compactMap { Int($0.trimmingCharacters(in: .whitespacesAndNewlines)) }
|
||
}
|
||
if let value = try? decodeIfPresent(Int.self, forKey: key) {
|
||
return [value]
|
||
}
|
||
return []
|
||
}
|
||
}
|