Skip to content

Commit

Permalink
designatedPath
Browse files Browse the repository at this point in the history
  • Loading branch information
intsig171 committed May 6, 2024
1 parent 40f223c commit f23f4ab
Show file tree
Hide file tree
Showing 13 changed files with 1,037 additions and 939 deletions.
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PODS:
- FBSnapshotTestCase/SwiftSupport (2.1.4):
- FBSnapshotTestCase/Core
- HandyJSON (5.0.0-beta.1)
- SmartCodable (3.3.2)
- SmartCodable (3.4.0)
- SnapKit (5.6.0)
- SQLiteRepairKit (1.3.0):
- WCDBOptimizedSQLCipher (~> 1.3.0)
Expand Down Expand Up @@ -49,7 +49,7 @@ SPEC CHECKSUMS:
CleanJSON: 910a36465ce4829e264a902ccf6d1455fdd9f980
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
HandyJSON: 582477127ab3ab65bd2e471815f1a7b846856978
SmartCodable: 44b817e837231549b1aae22f50b275eef6d09ba8
SmartCodable: 634142b85515a934e3c533f75444be33b8b74844
SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25
SQLiteRepairKit: a66145aadae91886c800f75e16f5cc6476af1a93
WCDB.swift: 39e28fe29b5a3bf2927d9fb9218978f19bd49ff0
Expand Down
4 changes: 2 additions & 2 deletions Example/Pods/Local Podspecs/SmartCodable.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,757 changes: 885 additions & 872 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ class MixDecodingViewController: BaseViewController {
"sub": [
"subDate": 1712491290,
"subColor": "7DA5E3",
"subData": "aHR0cHM6Ly93d3cucWl4aW4uY29t"
]
]

let option: SmartDecodingOption = .key(.firstLetterLower)

guard let model = SmartModel.deserialize(from: dict1, options: [option]) else { return }
print(model)
if let data = model.data, let url = String(data: data, encoding: .utf8) {
print(url)
// https://www.qixin.com
}
}
}

Expand All @@ -51,6 +56,7 @@ extension MixDecodingViewController {

var date1: Date?
var date2: Date?
var data: Data?
var url: URL?

var color: SmartColor?
Expand All @@ -61,6 +67,7 @@ extension MixDecodingViewController {
// case ignoreKey
case date1
case date2
case data
case url
case color
}
Expand All @@ -70,7 +77,8 @@ extension MixDecodingViewController {
[
CodingKeys.date1 <--- ["date", "date1"],
CodingKeys.date2 <--- "sub.subDate",
CodingKeys.color <--- "sub.subColor"
CodingKeys.color <--- "sub.subColor",
CodingKeys.data <--- "sub.subData"
]
}

Expand All @@ -82,6 +90,7 @@ extension MixDecodingViewController {
CodingKeys.url <--- SmartURLTransformer(prefix: "https://"),
CodingKeys.date1 <--- SmartDateFormatTransformer(format),
CodingKeys.date2 <--- SmartDateTransformer(),
CodingKeys.data <--- SmartDataTransformer()
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CustomDecodingValueViewContriller: BaseViewController {
"sub": [
"subDate": 1712491290,
"subColor": "7DA5E3",
"subData": "aHR0cHM6Ly93d3cucWl4aW4uY29t"
]
]
guard let model1 = SmartModel.deserialize(from: dict1) else { return }
Expand All @@ -42,6 +43,11 @@ class CustomDecodingValueViewContriller: BaseViewController {

print("\n")

if let data = model?.sub?.subData, let url = String(data: data, encoding: .utf8) {
print(url)
// https://www.qixin.com
}

guard let dataValue = model1.toDictionary() else { return }
print(dataValue)
}
Expand All @@ -64,9 +70,10 @@ extension CustomDecodingValueViewContriller {
var bool: Bool = false
var cgFloat: CGFloat = 0.0
var double: Double = 0.0

var date1: Date?
var date2: Date?

var url: URL?

var ignoreKey: String?
Expand All @@ -80,7 +87,6 @@ extension CustomDecodingValueViewContriller {
let format = DateFormatter()
format.dateFormat = "yyyy-MM-dd"
return [

CodingKeys.string <--- StringTransformer(),
CodingKeys.int <--- IntTransformer(),
CodingKeys.double <--- DoubleTransformer(),
Expand All @@ -98,15 +104,19 @@ extension CustomDecodingValueViewContriller {

var subDate: Date?
var subColor: SmartColor?
var subData: Data?


static func mappingForKey() -> [SmartKeyTransformer]? {
[
CodingKeys.subDate <--- "date2"
CodingKeys.subDate <--- "date2",
]
}

static func mappingForValue() -> [SmartValueTransformer]? {
[
CodingKeys.subData <--- SmartDataTransformer(),

CodingKeys.subDate <--- SmartDateTransformer(),
CodingKeys.subColor <--- SmartHexColorTransformer()
]
Expand Down
10 changes: 2 additions & 8 deletions Example/SmartCodable/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@
import UIKit
import SmartCodable


func isTypeDictionary<T: Decodable>(type: T.Type) -> Bool {
return T.self is Dictionary<String, String>.Type
}


class ViewController: UIViewController {


Expand All @@ -29,11 +23,11 @@ class ViewController: UIViewController {

dataArray = [
other,
smart_debug,
smart_test,
replace_HandyJSON,
smart_introduce,
smart_customDecoding,
smart_debug,
smart_case,
]

Expand Down Expand Up @@ -121,7 +115,7 @@ extension ViewController {
[
"title": "内部测试(请忽略)",
"list": [
["name": "测试代码", "vc": "TestViewController"],
["name": "测试代码1", "vc": "TestViewController"],
["name": "测试代码2", "vc": "Test2ViewController"],
["name": "测试代码3", "vc": "Test3ViewController"],

Expand Down
123 changes: 81 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,25 @@

【✅: 完美支持】【⚠️: 带缺陷的支持】【❌: 不支持】

| 🎯 特性 | 💬 特性说明 💬 | SmartCodable | HandyJSON |
| ------------------------- | ------------------------------------------------------------ | ------------ | --------- |
|**强大的兼容性** | 完美兼容:**字段缺失** & **字段值为nul** & **字段类型错误** |||
|**类型自适应** | 如JSON中是一个Int,但对应Model是String字段,会自动完成转化 |||
|**解析Any** | 支持解析 **[Any], [String: Any]** 等类型 |||
|**解码回调** | 支持Model解码完成的回调,即:**didFinishingMapping** |||
|**属性初始化值填充** | 当解析失败时,支持使用初始的Model属性的赋值。 |||
|**字符串的Model化** | 字符串是json字符串,支持进行Model化解析 |||
|**枚举的解析** | 当枚举解析失败时,支持兼容。 |||
|**自定义解析** - 重命名 | 自定义解码key(对解码的Model属性重命名) |||
|**自定义解析** - 忽略 | 忽略某个Model属性的解码 | ⚠️ ||
|**Model的继承** | 在model的继承关系下,Codable的支持力度较弱,使用不便(可以支持) |||
|**自定义解析路径** | 指定从json的层级开始解析 |||
|**超复杂的数据解码** | 解码过程中,多数据做进一步的整合/处理。如: 数据的扁平化处理 || ⚠️ |
|**解码性能** | 在解码性能上,SmartCodable 平均强 30% || ⚠️ |
|**异常解码日志** | 当解码异常进行了兼容处理时,提供排查日志 |||
|**安全性方面** | 底层实现的稳定性和安全性。 |||
| 序号 | 🎯 特性 | 💬 特性说明 💬 | SmartCodable | HandyJSON |
| ------------------------- | ------------------------------------------------------------ | ------------ | --------- | --------- |
| 1 | **强大的兼容性** | 完美兼容:**字段缺失** & **字段值为nul** & **字段类型错误** |||
| 2 | **类型自适应** | 如JSON中是一个Int,但对应Model是String字段,会自动完成转化 |||
| 3 | **解析Any** | 支持解析 **[Any], [String: Any]** 等类型 |||
| 4 | **解码回调** | 支持Model解码完成的回调,即:**didFinishingMapping** |||
| 5 | **属性初始化值填充** | 当解析失败时,支持使用初始的Model属性的赋值。 |||
| 6 | **字符串的Model化** | 字符串是json字符串,支持进行Model化解析 |||
| 7 | **枚举的解析** | 当枚举解析失败时,支持兼容。 |||
| 8 | **属性的自定义解析** - 重命名 | 自定义解码key(对解码的Model属性重命名) |||
| 9 | **属性的自定义解析** - 忽略 | 忽略某个Model属性的解码 |||
| 10 | **支持designatedPath** | 实现自定义解析路径 |||
| 11 | **Model的继承** | 在model的继承关系下,Codable的支持力度较弱,使用不便(可以支持) |||
| 12 | **自定义解析路径** | 指定从json的层级开始解析 |||
| 13 | **超复杂的数据解码** | 解码过程中,多数据做进一步的整合/处理。如: 数据的扁平化处理 || ⚠️ |
| 14 | **解码性能** | 在解码性能上,SmartCodable 平均强 30% || ⚠️ |
| 15 | **异常解码日志** | 当解码异常进行了兼容处理时,提供排查日志 |||
| 16 | **安全性方面** | 底层实现的稳定性和安全性。 |||
| 17 | **支持designatedPath** | 实现自定义解析路径 |||

整体来讲: SmartCodable 和 HandyJSON 相比,在功能和使用上相近。

Expand All @@ -47,15 +49,16 @@

有不少使用者提出了优化需求 或 新功能的要求。在这边逐一回复:

| 💡 建议列表 | 是否采纳 | 理由 |
| -------------------------------------------------- | -------- | ------------------------------------------------------------ |
|**#suggest 1 在mapping方法中支持解析忽略** || [不采纳的理由](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%201%20在mapping方法中支持解析忽略.md) |
|**#suggest 2 像HandyJSON一样支持继承关系的解析** || [不采纳的理由](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%202%20像HandyJSON一样支持继承关系的解析.md) |
|**#suggest 3 支持初始值填充** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%203%20支持属性初始化值填充.md) |
|**#suggest 4 提供HandyJSON的替换指导** || [替换指导](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%204%20使用SmartCodable%20平替%20HandyJSON.md) |
|**#suggest 5 提供全局的Key映射策略** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%205%20提供全局的Key映射策略.md) |
|**#suggest 6 支持UIColor的解析** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%206%20支持由hex颜色解析到UIColor.md) |
|**#suggest 7 增加单个Value的自定义转换策略** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%207%20增加单个Value的自定义转换策略.md) |
| 💡 建议列表 | 是否采纳 | 理由 |
| --------------------------------------------------- | -------- | ------------------------------------------------------------ |
|**#suggest 1 在mapping方法中支持解析忽略** || [不采纳的理由](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%201%20在mapping方法中支持解析忽略.md) |
|**#suggest 2 像HandyJSON一样支持继承关系的解析** || [不采纳的理由](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%202%20像HandyJSON一样支持继承关系的解析.md) |
|**#suggest 3 支持初始值填充** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%203%20支持属性初始化值填充.md) |
|**#suggest 4 提供HandyJSON的替换指导** || [替换指导](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%204%20使用SmartCodable%20平替%20HandyJSON.md) |
|**#suggest 5 提供全局的Key映射策略** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%205%20提供全局的Key映射策略.md) |
|**#suggest 6 支持UIColor的解析** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%206%20支持由hex颜色解析到UIColor.md) |
|**#suggest 7 增加单个Value的自定义转换策略** || [实现逻辑](https://github.com/intsig171/SmartCodable/blob/main/Document/建议/%23suggest%207%20增加单个Value的自定义转换策略.md) |
|**#suggest 8 支持designatedPath的自定义路径解析** || 参考HandyJSON实现 |


## 使用SmartCodable 平替 HandyJSON
Expand Down Expand Up @@ -343,6 +346,26 @@ struct Model: SmartCodable {

当然,也可以在这里进行key的重命名。



#### @IgnoredKey

也可以选择使用 **@IgnoredKey** 属性包装器忽略某个Key的解析。

```
struct Home: SmartCodable {
var name: String = ""
@IgnoredKey
var age: [Any] = ["1"]
@IgnoredKey
var area: String = "area"
}
```

严格意义上来说: 要忽略解析只能通过重写 **CodingKeys**。 作者通过**@IgnoredKey** 的标记打断了解析过程(还是会进入解析 ),返回了该属性的初始化值。



### [解码中] Key的映射策略

#### 全局的Key映射策略
Expand Down Expand Up @@ -481,6 +504,7 @@ struct SmartModel: SmartCodable {
var date1: Date?
var date2: Date?
var url: URL?
var data: Data?
// value的解析策略
static func mappingForValue() -> [SmartValueTransformer]? {
Expand All @@ -489,7 +513,8 @@ struct SmartModel: SmartCodable {
return [
CodingKeys.url <--- SmartURLTransformer(prefix: "https://"),
CodingKeys.date2 <--- SmartDateTransformer(),
CodingKeys.date1 <--- SmartDateFormatTransformer(format)
CodingKeys.date1 <--- SmartDateFormatTransformer(format),
CodingKeys.data <--- SmartDataTransformer()
]
}
}
Expand All @@ -502,6 +527,7 @@ struct SmartModel: SmartCodable {
* Date
* UIColor
* URL
* Data

如需其他类型可以提 **issue**

Expand Down Expand Up @@ -553,25 +579,38 @@ class Model: SmartDecodable {

SmartCodable鼓励从根本上解决解析中的问题,即:不需要用到SmartCodable的兼容逻辑。 如果出现解析兼容的情况,修改Model中属性的定义,或要求数据方进行修正。为了更方便的定位问题。

调试日志,将提供辅助信息,帮助定位问题:

* 错误类型: 错误的类型信息
* 模型名称:发生错误的模型名出
* 数据节点:发生错误时,数据的解码路径。
* 属性信息:发生错误的字段名。
* 错误原因: 错误的具体原因。
调试日志,将提供辅助信息

```
================ [SmartLog Error] ================
错误类型: '找不到键的错误'
模型名称:Array<Class>
数据节点:Index 0 → students → Index 0
属性信息:(名称)more
错误原因: No value associated with key CodingKeys(stringValue: "more", intValue: nil) ("more").
==================================================
======================== [Smart Decoding Log] ========================
Family 👈🏻 👀
|- name : Expected to decode String but found an array instead.
|- location: Expected to decode String but found an array instead.
|- date : Expected to decode Date but found an array instead.
|> father: Father
|- name: Expected String value but found null instead.
|- age : Expected to decode Int but found a string/data instead.
|> dog: Dog
|- hobby: Expected to decode String but found a number instead.
|> sons: [Son]
|- [Index 0] hobby: Expected to decode String but found a number instead.
|- [Index 0] age : Expected to decode Int but found a string/data instead.
|- [Index 1] age : Expected to decode Int but found an array instead.
=========================================================================
```

你可以通过SmartConfig 调整日志的相关设置。
新版本的日志:

* 以Model为单元进行和合并,减少了日志的数量。

* 合并相同的解析错误,减少了相同日志的干扰。
* 简化了日志内容,让日志一目了然。









Expand Down
2 changes: 1 addition & 1 deletion SmartCodable.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

Pod::Spec.new do |s|
s.name = 'SmartCodable'
s.version = '3.3.2'
s.version = '3.4.0'
s.summary = '数据解析库'

s.homepage = 'https://github.com/intsig171'
Expand Down
Loading

0 comments on commit f23f4ab

Please sign in to comment.