Skip to content

Commit

Permalink
完成SmartUpdater的优化
Browse files Browse the repository at this point in the history
  • Loading branch information
intsig171 committed Jul 26, 2024
1 parent 48d5913 commit 988127a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ class Introduce_11ViewController: BaseCompatibilityViewController {
var dest = Model(name: "xiaoming", hobby: "football")
let src = Model(name: "dahuang", hobby: "sleep")

print(dest)
SmartUpdater.update(&dest, from: src, keyPath: \.name)

print(dest)

SmartUpdater.update(&dest, from: src, keyPaths: (\.name, \.hobby))

print(dest)
// print(dest)
// SmartUpdater.update(&dest, from: src, keyPath: \.name)
//
// print(dest)
//
// SmartUpdater.update(&dest, from: src, keyPaths: (\.name, \.hobby))
//
// print(dest)
}
}

Expand Down
34 changes: 28 additions & 6 deletions Example/SmartCodable/Test2ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation
import SmartCodable
import HandyJSON

import BTPrint



Expand All @@ -19,17 +19,39 @@ class Test2ViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()

let dic: [String : Any] = [
"timestamp": "1721721316"
var dic: [String : Any] = [
"a1": "1111",
"a2": 11111,
"a3": [
"b1": "2222",
"b2": 2222,
"b3": [1, 2, 3]
]
]
let dic2: [String : Any] = [
"a2": 2222,
"a3": [
"b3": [100, 200, 300]
]
]

let model = Model.deserialize(from: dic)
smartPrint(value: model)
guard var model = Model.deserialize(from: dic) else { return }


let json2 = dic2.bt_toJSONString()

SmartUpdater.update(&model, from: json2)
smartPrint(value: model)
}
struct Model: SmartCodable {
var timestamp: UInt32?
var a1: String = ""
var a2: Int = 0
var a3: SubModel = SubModel()
}

struct SubModel: SmartCodable {
var b1: String = ""
var b2: Int = 0
var b3: [Int] = []
}
}
114 changes: 50 additions & 64 deletions SmartCodable/Classes/SmartCodable/SmartUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,81 +8,67 @@
import Foundation


/** 关于upate的实现【临时的实现方案】
1. 没有找到有效的泛型方法,主要是因为WritableKeyPath<T, K>的判断问题。WritableKeyPath<T, Int> 和 WritableKeyPath<T, Any> 并不是一个类型。
2. 尝试了AnyKeyPath, 在使用AnyKeyPath.valueType(typeOf获取类型),因为WritableKeyPath无法使用运行时类型,失败了。
3. 尝试了泛型,反射等,都失败。
4. 欢迎提供好的思路。
*/

public struct SmartUpdater<T> {
public struct SmartUpdater<T: SmartCodable> {

public static func update<K1>(_ dest: inout T, from src: T, keyPath: Path<K1>) {
/// This method is used to parse JSON data from a Data object and use the resulting dictionary to update a target object.
/// - Parameters:
/// - dest: A reference to the target object (the inout keyword indicates that this object will be modified within the method).
/// - src: A Data object containing the JSON data.
public static func update(_ dest: inout T, from src: Data?) {

dest[keyPath: keyPath] = src[keyPath: keyPath]
}

public static func update<K1, K2>(_ dest: inout T, from src: T, keyPaths: Path2<K1, K2>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
}

public static func update<K1, K2, K3>(_ dest: inout T, from src: T, keyPaths: Path3<K1, K2, K3>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
dest[keyPath: keyPaths.2] = src[keyPath: keyPaths.2]
guard let src = src else { return }

guard let dict = try? JSONSerialization.jsonObject(with: src, options: .mutableContainers) as? [String: Any] else {
return
}
update(&dest, from: dict)
}

public static func update<K1, K2, K3, K4>(_ dest: inout T, from src: T, keyPaths: Path4<K1, K2, K3, K4>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
dest[keyPath: keyPaths.2] = src[keyPath: keyPaths.2]
dest[keyPath: keyPaths.3] = src[keyPath: keyPaths.3]
}

public static func update<K1, K2, K3, K4, K5>(_ dest: inout T, from src: T, keyPaths: Path5<K1, K2, K3, K4, K5>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
dest[keyPath: keyPaths.2] = src[keyPath: keyPaths.2]
dest[keyPath: keyPaths.3] = src[keyPath: keyPaths.3]
dest[keyPath: keyPaths.4] = src[keyPath: keyPaths.4]
/// This method is used to parse JSON data from a Data object and use the resulting dictionary to update a target object.
/// - Parameters:
/// - dest: A reference to the target object (the inout keyword indicates that this object will be modified within the method).
/// - src: A String object containing the JSON data.
public static func update(_ dest: inout T, from src: String?) {

guard let src = src else { return }

guard let data = src.data(using: .utf8) else { return }

guard let dict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { return }

update(&dest, from: dict)
}

public static func update<K1, K2, K3, K4, K5, K6>(_ dest: inout T, from src: T, keyPaths: Path6<K1, K2, K3, K4, K5, K6>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
dest[keyPath: keyPaths.2] = src[keyPath: keyPaths.2]
dest[keyPath: keyPaths.3] = src[keyPath: keyPaths.3]
dest[keyPath: keyPaths.4] = src[keyPath: keyPaths.4]
dest[keyPath: keyPaths.5] = src[keyPath: keyPaths.5]
}

public static func update<K1, K2, K3, K4, K5, K6, K7>(_ dest: inout T, from src: T, keyPaths: Path7<K1, K2, K3, K4, K5, K6, K7>) {
dest[keyPath: keyPaths.0] = src[keyPath: keyPaths.0]
dest[keyPath: keyPaths.1] = src[keyPath: keyPaths.1]
dest[keyPath: keyPaths.2] = src[keyPath: keyPaths.2]
dest[keyPath: keyPaths.3] = src[keyPath: keyPaths.3]
dest[keyPath: keyPaths.4] = src[keyPath: keyPaths.4]
dest[keyPath: keyPaths.5] = src[keyPath: keyPaths.5]
dest[keyPath: keyPaths.6] = src[keyPath: keyPaths.6]
/// This method is used to parse JSON data from a Data object and use the resulting dictionary to update a target object.
/// - Parameters:
/// - dest: A reference to the target object (the inout keyword indicates that this object will be modified within the method).
/// - src: A Dictionary object containing the JSON data.
public static func update(_ dest: inout T, from src: [String: Any]?) {

guard let src = src else { return }

var destDict = dest.toDictionary() ?? [:]
updateDict(&destDict, from: src)

print(destDict)

if let model = T.deserialize(from: destDict) {
dest = model
}
}
}

extension SmartUpdater {
public typealias Path<K> = WritableKeyPath<T, K>
public typealias Path2<K1, K2>
= (Path<K1>, Path<K2>)
public typealias Path3<K1, K2, K3>
= (Path<K1>, Path<K2>, Path<K3>)
public typealias Path4<K1, K2, K3, K4>
= (Path<K1>, Path<K2>, Path<K3>, Path<K4>)
public typealias Path5<K1, K2, K3, K4, K5>
= (Path<K1>, Path<K2>, Path<K3>, Path<K4>, Path<K5>)
public typealias Path6<K1, K2, K3, K4, K5, K6>
= (Path<K1>, Path<K2>, Path<K3>, Path<K4>, Path<K5>, Path<K6>)
public typealias Path7<K1, K2, K3, K4, K5, K6, K7>
= (Path<K1>, Path<K2>, Path<K3>, Path<K4>, Path<K5>, Path<K6>, Path<K7>)

/// 合并字典,将src合并到dest
/// - Parameters:
/// - dest: 目标字典
/// - src: 源字典
fileprivate static func updateDict(_ dest: inout [String: Any], from src: [String: Any]) {
dest.merge(src) { _, new in
return new
}
}
}


0 comments on commit 988127a

Please sign in to comment.