处理后端提供的各种神奇 Json 数据,而做的解析保护
使用 Swift Package Manager:
处理 json 数据应该为布尔值,但是实际上并非布尔值的问题
{
"true": true,
"false": "FALSE"
}
将要解析成 Bool 型态的 property 套上 @BoolProtection
进行型态保护
struct BoolObject: Decodable
{
@BoolProtection
var `true`: Bool?
@BoolProtection
var `false`: Bool?
}
支持型态(字符串不区分大小写):
- true: 1、“true”、“yes”
- false: 0、“false”、“no”
保护 json key 时有时无的情况
正常情況:
{
"data": {
"name": "Some one",
"age": 11
}
}
錯誤情況:
{
"error": "token is expired."
}
将 key 可能消失的 property 加上 @MissingKeyProtection
进行保护
struct UserData: Decodable
{
@MissingKeyProtection
var data: UserInfo?
@MissingKeyProtection
var error: String?
}
处理 json 数据应该为数字型态,但是实际上可能为字符串型态的问题
包含 MissingKeyProtection 的功能
{
"city": "高雄市",
"lat": "22.78806",
"lng": "120.24257"
}
将要解析成数字型态的 property 套上 @NumberProtection
进行型态保护
struct BikeLocation: Decodable
{
var city: String?
@NumberProtection
var lat: CLLocationDegrees?
@NumberProtection
var lng: CLLocationDegrees?
}
支持的数字型态:
- Int
- Float
- Double
- Decimal
- 含以上型态的枚举 eg:
enum Type: Int
(需套用 NumberType 这个 protocol)
处理 json 数据应该为数字阵列型态,但是实际上可能为字符串阵列型态的问题
{
"index": ["10", "20", "50", "100"]
}
将要解析成数字阵列型态的 property 套上 @NumbersProtection
进行型态保护
struct Library: Decodable
{
@NumbersProtection
var index: [Int]?
}
支持的数字型态:
- 与 NumberProtection 相同
处理 json 里应为数字内用的 jsonArray 数据,但实际上是 String 型态的问题
{
"dices": "[1, 5.2, 1.0]"
}
将要解析成数字阵列型态的 property 套上 @NumberArrayProtection
进行型态保护
struct NumberArray: Decodable
{
@NumberArrayProtection
var dices: [Double]?
}
支持的数字型态 (阵列内的数字型态必定要相同,不能混入字符串):
- 与 NumberProtection 相同
处理 json 里应为 jsonObject 数据,但实际上是 String 型态的问题
{
"num": 1,
"sub": "{\"num\": 22}"
}
将要解析成物件的 property 套上 @ObjectProtection
进行型态保护
struct Info: Decodable
{
var num: Int?
@ObjectProtection
var sub: Sub?
}
extension Info
{
struct Sub: Decodable
{
var num: Int?
}
}
解决 json 数据里的时间各式不统一的问题, 并且避免 json 数据型态不正确的问题
{
"updateTime": 1694102400,
"expiredDate": "202309080100"
}
将要解析成日期阵列型态的 property 套上 @DateProtection
进行型态保护
struct DateObject: Decodable
{
let updateTime: Date?
@DateProtection(configuration: DateConfiguration.self)
private(set)
var expiredDate: Date?
}
并且继承 DateConfigurate 提供相关设定
extension DateObject
{
struct DateConfiguration: DateConfigurate
{
static var option: DateConfigurateOption {
.dateFormat("yyyyMMddhhss", timeZone: TimeZone(abbreviation: "GMT+0800"))
}
}
}
设定选项:
- 时间格式 (yyyyMMdd 等格式) 与时区
- 时间戳(基本单位为秒(Second))
- 时间戳(基本单位为毫秒(millisecond))
- iso8601(是否有毫秒)
支持型态:
- 字符串
- 任何数字型态
将 json 里的字符串解析成为 UIImage 型态
⚠️ :专案内需有同名的图片档案
避免 json 里的字符串为空时,解析成 URL 型态会解析失败的问题
{
"homePageUrl": "https://www.google.com",
"detailPageUrl": ""
}
将要解析成 URL 的 property 套上 @URLProtection
进行型态保护
struct URLObject: Decodable
{
private(set)
var homePageUrl: URL?
@URLProtection
var detailPageUrl: URL?
}
这是唯一不做保护的功能,仅做解析 Json 数据时同时做 AES256 解密
使用需继承 AESAdopter 提供相关解密资讯
struct AESAdopting: AESAdopter
{
static var key: String {
"MnoewgUZrgt5Rk08MtESwHvgzY7ElaEq"
}
static var iv: String? {
"rtCG5mdgtlCtbyI4"
}
static var options: DTAES.Options {
[.pkc7Padding, .zeroPadding]
}
}
然后在需解密的 property 时加上 @AESDecoder
,即可在完成解析后并且做解密的动作
struct AESObject: Decodable
{
@AESDecoder(adopter: AESAdopting.self)
var url: String?
}
支持型态:
- 字符串
- 字符串阵列
保护同变数在不同 json 数据情境下,有复数的 key 存在的问题