From 7c20dd24c1f9c3ad102dc41fa46290dc5a3981db Mon Sep 17 00:00:00 2001 From: Mccc Date: Fri, 5 Jul 2024 18:17:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=AE=E7=82=B9=E6=95=B0?= =?UTF-8?q?=E8=BD=ACString=E7=B1=BB=E5=9E=8B=E7=B2=BE=E5=BA=A6=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Example/Podfile.lock | 4 +- .../Local Podspecs/SmartCodable.podspec.json | 4 +- Example/Pods/Manifest.lock | 4 +- .../SmartCodable/SmartCodable-Info.plist | 2 +- .../Base/NSDictionary+Extension.swift | 5 + .../SmartCodable/Test2ViewController.swift | 80 ++----- .../SmartCodable/Test3ViewController.swift | 28 +-- Example/SmartCodable/TestViewController.swift | 223 +++++++++++++++++- .../BaseData_FloatViewController.swift" | 9 +- .../BaseData_StringViewController.swift" | 6 +- SmartCodable.podspec | 2 +- .../Impl/JSONDecoderImpl+KeyedContainer.swift | 8 +- ...JSONDecoderImpl+SingleValueContainer.swift | 8 +- .../JSONDecoderImpl+UnkeyedContainer.swift | 4 +- .../Patcher/Patcher+Transformer.swift | 129 +++++----- .../Classes/JSONDecoder/Patcher/Patcher.swift | 12 +- 16 files changed, 336 insertions(+), 192 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 970fe59..ac57921 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -8,7 +8,7 @@ PODS: - FBSnapshotTestCase/SwiftSupport (2.1.4): - FBSnapshotTestCase/Core - HandyJSON (5.0.0-beta.1) - - SmartCodable (4.1.0) + - SmartCodable (4.1.1) - SnapKit (5.6.0) DEPENDENCIES: @@ -39,7 +39,7 @@ SPEC CHECKSUMS: CleanJSON: 910a36465ce4829e264a902ccf6d1455fdd9f980 FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a HandyJSON: 582477127ab3ab65bd2e471815f1a7b846856978 - SmartCodable: 04f61a30bd6567fc15b71e718e1aee4766956e55 + SmartCodable: 092fd8c698dc958fc95e1d93baf3b497f9ab1715 SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 PODFILE CHECKSUM: 7f3af03f81934df0c035518074a7abbec8fa9d3f diff --git a/Example/Pods/Local Podspecs/SmartCodable.podspec.json b/Example/Pods/Local Podspecs/SmartCodable.podspec.json index b7a75a4..44c7fc8 100644 --- a/Example/Pods/Local Podspecs/SmartCodable.podspec.json +++ b/Example/Pods/Local Podspecs/SmartCodable.podspec.json @@ -1,6 +1,6 @@ { "name": "SmartCodable", - "version": "4.1.0", + "version": "4.1.1", "summary": "数据解析库", "homepage": "https://github.com/intsig171", "license": { @@ -12,7 +12,7 @@ }, "source": { "git": "https://github.com/intsig171/SmartCodable.git", - "tag": "4.1.0" + "tag": "4.1.1" }, "platforms": { "ios": "11.0", diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index 970fe59..ac57921 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -8,7 +8,7 @@ PODS: - FBSnapshotTestCase/SwiftSupport (2.1.4): - FBSnapshotTestCase/Core - HandyJSON (5.0.0-beta.1) - - SmartCodable (4.1.0) + - SmartCodable (4.1.1) - SnapKit (5.6.0) DEPENDENCIES: @@ -39,7 +39,7 @@ SPEC CHECKSUMS: CleanJSON: 910a36465ce4829e264a902ccf6d1455fdd9f980 FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a HandyJSON: 582477127ab3ab65bd2e471815f1a7b846856978 - SmartCodable: 04f61a30bd6567fc15b71e718e1aee4766956e55 + SmartCodable: 092fd8c698dc958fc95e1d93baf3b497f9ab1715 SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 PODFILE CHECKSUM: 7f3af03f81934df0c035518074a7abbec8fa9d3f diff --git a/Example/Pods/Target Support Files/SmartCodable/SmartCodable-Info.plist b/Example/Pods/Target Support Files/SmartCodable/SmartCodable-Info.plist index c8bd5a0..3fdec7b 100644 --- a/Example/Pods/Target Support Files/SmartCodable/SmartCodable-Info.plist +++ b/Example/Pods/Target Support Files/SmartCodable/SmartCodable-Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 4.1.0 + 4.1.1 CFBundleSignature ???? CFBundleVersion diff --git a/Example/SmartCodable/Base/NSDictionary+Extension.swift b/Example/SmartCodable/Base/NSDictionary+Extension.swift index 8ef1144..2a575e6 100644 --- a/Example/SmartCodable/Base/NSDictionary+Extension.swift +++ b/Example/SmartCodable/Base/NSDictionary+Extension.swift @@ -22,6 +22,11 @@ extension Dictionary { return nil } } + + func toData() -> Data? { + guard JSONSerialization.isValidJSONObject(self) else { return nil } + return try? JSONSerialization.data(withJSONObject: self) + } } diff --git a/Example/SmartCodable/Test2ViewController.swift b/Example/SmartCodable/Test2ViewController.swift index ba967bb..a9d7505 100644 --- a/Example/SmartCodable/Test2ViewController.swift +++ b/Example/SmartCodable/Test2ViewController.swift @@ -18,76 +18,34 @@ class Test2ViewController: BaseViewController { override func viewDidLoad() { super.viewDidLoad() + - SmartConfig.debugMode = .verbose - - let dict1: [String: Any] = [ - : - ] - - let dict2: [String: Any] = [ - "arr": NSNull(), - "optionalArr": NSNull(), - "arr1": NSNull(), - "optionalArr1": NSNull() - ] - - let dict3: [String: Any] = [ - "arr": 1, - "optionalArr": 2, - "arr1": 3, - "optionalArr1": 4 - ] - - let dict4: [String: Any] = [ - "arr": [[ "name": "mccc1" ], [ "name": "mccc2" ]], - "optionalArr": [[ "name": "mccc1" ], [ "name": "mccc2" ]], + let dict: [String: Any] = [ + "key": 4.99 ] + let data = dict.toData()! + let decoder = JSONDecoder() - print("-------------- 无key") - if let model = FeedModel.deserialize(from: dict1) { - smartPrint(value: model) - } - - print("-------------- null") - if let model = FeedModel.deserialize(from: dict2) { - smartPrint(value: model) + do { + let model = try decoder.decode(Model.self, from: data) + print(model) + } catch { + print(error) } - print("-------------- 类型错误") - if let model = FeedModel.deserialize(from: dict3) { - smartPrint(value: model) - } - print("-------------- 解析正确的") - if let model = FeedModel.deserialize(from: dict4) { - smartPrint(value: model) - } } - //模型 - struct FeedModel: SmartCodable { -// var arr: [Int] = [] -// var optionalArr: [Int]? -// var optionalArr: [Int]? = [1, 1, 1] - -// var arr: [Int?] = [] -// var optionalArr: [Int?]? -// var optionalArr: [Int?]? = [1, 1, 1] - -// @SmartAny -// var arr: [Any] = [] -// @SmartAny -// var optionalArr: [Any]? - - - var arr: [SubModel] = [] - var optionalArr: [SubModel]? - } - - struct SubModel: SmartCodable { - var name: String? + struct Model: Codable { + var key: String? + + init(from decoder: any Decoder) throws { + let container: KeyedDecodingContainer = try decoder.container(keyedBy: Test2ViewController.Model.CodingKeys.self) + let double = try container.decodeIfPresent(Double.self, forKey: Test2ViewController.Model.CodingKeys.key) + + self.key = "\(String(describing: double))" + } } } diff --git a/Example/SmartCodable/Test3ViewController.swift b/Example/SmartCodable/Test3ViewController.swift index 248b5ad..cd0782f 100644 --- a/Example/SmartCodable/Test3ViewController.swift +++ b/Example/SmartCodable/Test3ViewController.swift @@ -19,12 +19,14 @@ class Test3ViewController: BaseViewController { override func viewDidLoad() { super.viewDidLoad() + SmartConfig.debugMode = .none + let dict: [String: Any] = [ - "subModel": [ - "name": NSNull() - ], - "dict": ["a":1, "b": NSNull(), "c": ["aa": 2]], - "arr": [1, "2", "Mccc", [1,2,3]] + "key": 5.1, + "key1":5.2, + "key2": 1.99, + "key3": 4.99, + "key4": 99.99, ] if let model = Model.deserialize(from: dict) { smartPrint(value: model) @@ -32,17 +34,11 @@ class Test3ViewController: BaseViewController { } struct Model: SmartCodable { - @SmartAny - var dict: Any? - - @SmartAny - var arr: Any? - -// var subModel: SubModel? - } - - struct SubModel: SmartCodable { - var name: String? + var key: String = "" + var key1: String = "" + var key2: String = "" + var key3: String = "" + var key4: String = "" } } diff --git a/Example/SmartCodable/TestViewController.swift b/Example/SmartCodable/TestViewController.swift index 414fe6a..2e5e49a 100644 --- a/Example/SmartCodable/TestViewController.swift +++ b/Example/SmartCodable/TestViewController.swift @@ -46,21 +46,224 @@ class TestViewController: BaseViewController { - let arr = [ - ["name": "mccc1", "age": 20, "hobby": [1, 2, 3, "4"]], - ["name": "mccc2", "age": 30], - ] + let json = """ + + { + "baseAppDrainage": "", + "adChannel": "0", + "versionInfo": { + "version": "1.0.0", + "build": 1, + "createTime": "2024-07-02 18:59:28", + "id": 1257772650835476480, + "packageName": "com.elevrin.app" + }, + "configDefault": { + "IPFiltration": [ + "CHINA", + "CHINESE", + "CINEMA", + "CN", + "COMIC", + "CONSTANTIN", + "DISNEY", + "DREAMWORK", + "ENTERTAINMENT", + "EUROPACORP", + "FILM", + "FOCUS", + "GAUMONT", + "GOOGLE", + "HEIDI", + "HOLLYWOOD", + "HULU", + "IMAGE", + "IQIYI", + "LARICK", + "LEGENDARY", + "LIONSGATE", + "MARVEL", + "MEDIA", + "MIRAMAX", + "NETFLIX", + "NEW LINE", + "PARAMOUNT", + "PEACOCK", + "PHILO", + "PICTURE", + "PIXAR", + "SONY", + "STARLIGHT", + "STARZ", + "STUDIO", + "STX", + "TENCENT", + "TOUCHSTONE", + "TUBI", + "TV", + "UNIVERSAL", + "CHINANET", + "VIKI", + "ZEUS", + "VUDU", + "WARNER", + "WEINSTEIN" + ] + }, + "eventConfig": { + "returnDetail": [], + "eventType": "", + "returnDetailAd": "", + "adType": [] + }, + "messagePush": "", + "com.elevrin.app": [], + "Home_Data": [ + { + "data": [ + { + "vodeo": 28407, + "type": "movie" + }, + { + "vodeo": 28493, + "type": "movie" + }, + { + "vodeo": 24179, + "type": "movie" + }, + { + "vodeo": 28367, + "type": "movie" + }, + { + "vodeo": 20791, + "type": "movie" + } + ], + "level": 0, + "mode": 0, + "name": "Home Carousel" + }, + { + "data": [ + { + "vodeo": 20791, + "type": "movie" + }, + { + "vodeo": 28303, + "type": "movie" + }, + { + "vodeo": 28211, + "type": "movie" + }, + { + "vodeo": 28236, + "type": "movie" + }, + { + "vodeo": 28220, + "type": "movie" + } + ], + "level": 1, + "mode": 0, + "name": "Trending", + "id": 1 + }, + { + "data": [ + { + "vodeo": 14064, + "type": "tv" + }, + { + "vodeo": 14053, + "type": "tv" + }, + { + "vodeo": 14056, + "type": "tv" + }, + { + "vodeo": 14043, + "type": "tv" + }, + { + "vodeo": 14052, + "type": "tv" + } + ], + "level": 2, + "mode": 0, + "name": "Popular TV Shows", + "id": 2 + }, + { + "data": [ + { + "vodeo": 27915, + "type": "movie" + }, + { + "vodeo": 25650, + "type": "movie" + }, + { + "vodeo": 28380, + "type": "movie" + }, + { + "vodeo": 28383, + "type": "movie" + }, + { + "vodeo": 28381, + "type": "movie" + } + ], + "level": 3, + "mode": 0, + "name": "Popular Movies", + "id": 3 + } + ], + "playSubTypeRatio": [], + "privacyLink": "https://catfight.top" + } + + """ - if let model = [FeedModel].deserialize(from: arr) { + if let model = NNInfos.deserialize(from: json) { smartPrint(value: model) } } - //模型 - struct FeedModel: SmartCodable { - var name: String = "" - var age: Int? - var hobby: [String] = [] + struct NNInfos: SmartCodable { + var version: String = "" + var build: Int = -1 + var ipfilters: [String] = [] + var privacyLink: String = "" + + static func mappingForKey() -> [SmartKeyTransformer]? { + let versionKey = "versionInfo".fixValue + "." + "version".fixValue + let buildKey = "versionInfo".fixValue + "." + "build".fixValue + let ipfilesKey = "configDefault".fixValue + "." + "IPFiltration".fixValue + return [ + CodingKeys.version <--- versionKey, + CodingKeys.build <--- buildKey, + CodingKeys.ipfilters <--- ipfilesKey, + CodingKeys.privacyLink <--- "privacyLink".fixValue + ] + } + } +} +extension String { + var fixValue: String { + return self } } diff --git "a/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_FloatViewController.swift" "b/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_FloatViewController.swift" index 711d242..7c7aba4 100644 --- "a/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_FloatViewController.swift" +++ "b/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_FloatViewController.swift" @@ -30,14 +30,7 @@ class BaseData_FloatViewController: BaseViewController { } """ guard let model = CompatibleFloat.deserialize(from: json) else { return } - print(model.floatValue) - print(model.floatValue1) - print(model.floatValue2) - print(model.floatValue3) - print(model.floatValue4 as Any) - - print(model.cgfloatValue) - print(model.doubleValue) + smartPrint(value: model) /** 0.0 diff --git "a/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_StringViewController.swift" "b/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_StringViewController.swift" index 04e4f7c..e6c2ec6 100644 --- "a/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_StringViewController.swift" +++ "b/Example/SmartCodable/\346\265\213\350\257\225\347\224\250\344\276\213/\350\247\243\347\240\201/\346\225\260\346\215\256\346\265\213\350\257\225/BaseData/BaseData_StringViewController.swift" @@ -28,11 +28,7 @@ class BaseData_StringViewController: BaseViewController { ] as [String : Any] guard let feed = CompatibleString.deserialize(from: dict) else { return } - print("string1的值为", feed.string1) - print("string2的值为", feed.string2) - print("string3的值为", feed.string3) - print("string4的值为", feed.string4 ?? "") - print("string5的值为", feed.string5) + smartPrint(value: feed) /** string1的值为 123 diff --git a/SmartCodable.podspec b/SmartCodable.podspec index 4f57820..b532fd5 100644 --- a/SmartCodable.podspec +++ b/SmartCodable.podspec @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.name = 'SmartCodable' - s.version = '4.1.0' + s.version = '4.1.1' s.summary = '数据解析库' s.homepage = 'https://github.com/intsig171' diff --git a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+KeyedContainer.swift b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+KeyedContainer.swift index c50da0b..2b05ae3 100644 --- a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+KeyedContainer.swift +++ b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+KeyedContainer.swift @@ -337,10 +337,10 @@ extension JSONDecoderImpl.KeyedContainer { return decoded } - guard case .string(let bool) = value else { + guard case .string(let string) = value else { return optionalDecode(forKey: key) } - return bool + return string } func decodeIfPresent(_ type: Float.Type, forKey key: K) throws -> Float? { @@ -483,7 +483,7 @@ extension JSONDecoderImpl.KeyedContainer { SmartLog.createLog(impl: impl, forKey: key, value: value, type: T.self) - if let decoded = Patcher.convertToType(from: value.peel) { + if let decoded = Patcher.convertToType(from: value, impl: impl) { return decoded } else if let initializer: T = impl.cache.getValue(forKey: key) { return initializer @@ -510,7 +510,7 @@ extension JSONDecoderImpl.KeyedContainer { } SmartLog.createLog(impl: impl, forKey: key, value: value, type: T.self) - if let decoded = Patcher.convertToType(from: value.peel) { + if let decoded = Patcher.convertToType(from: value, impl: impl) { return decoded } else { return try fillDefault() diff --git a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+SingleValueContainer.swift b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+SingleValueContainer.swift index 0018cd0..5aeeba6 100644 --- a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+SingleValueContainer.swift +++ b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+SingleValueContainer.swift @@ -36,7 +36,7 @@ extension JSONDecoderImpl { extension JSONDecoderImpl.SingleValueContainer { func decode(_: Bool.Type) throws -> Bool { guard case .bool(let bool) = self.value else { - if let trans = Patcher.convertToType(from: value.peel) { + if let trans = Patcher.convertToType(from: value, impl: impl) { return trans } throw self.impl.createTypeMismatchError(type: Bool.self, value: self.value) @@ -47,7 +47,7 @@ extension JSONDecoderImpl.SingleValueContainer { func decode(_: String.Type) throws -> String { guard case .string(let string) = self.value else { - if let trans = Patcher.convertToType(from: value.peel) { + if let trans = Patcher.convertToType(from: value, impl: impl) { return trans } throw self.impl.createTypeMismatchError(type: String.self, value: self.value) @@ -112,7 +112,7 @@ extension JSONDecoderImpl.SingleValueContainer { do { return try self.impl.unwrapFixedWidthInteger(from: self.value, as: T.self) } catch { - if let trnas = Patcher.convertToType(from: value.peel) { + if let trnas = Patcher.convertToType(from: value, impl: impl) { return trnas } else { throw error @@ -124,7 +124,7 @@ extension JSONDecoderImpl.SingleValueContainer { do { return try self.impl.unwrapFloatingPoint(from: self.value, as: T.self) } catch { - if let trnas = Patcher.convertToType(from: value.peel) { + if let trnas = Patcher.convertToType(from: value, impl: impl) { return trnas } else { throw error diff --git a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+UnkeyedContainer.swift b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+UnkeyedContainer.swift index d5df162..11c6d21 100644 --- a/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+UnkeyedContainer.swift +++ b/SmartCodable/Classes/JSONDecoder/Decoder/Impl/JSONDecoderImpl+UnkeyedContainer.swift @@ -224,7 +224,7 @@ extension JSONDecoderImpl.UnkeyedContainer { SmartLog.createLog(impl: impl, forKey: key, value: value, type: T.self) - if let decoded = Patcher.convertToType(from: value.peel) { + if let decoded = Patcher.convertToType(from: value, impl: impl) { self.currentIndex += 1 return decoded } else { @@ -356,7 +356,7 @@ extension JSONDecoderImpl.UnkeyedContainer { } let key = _JSONKey(index: self.currentIndex) SmartLog.createLog(impl: impl, forKey: key, value: value, type: T.self) - if let decoded = Patcher.convertToType(from: value.peel) { + if let decoded = Patcher.convertToType(from: value, impl: impl) { self.currentIndex += 1 return decoded } else { diff --git a/SmartCodable/Classes/JSONDecoder/Patcher/Patcher+Transformer.swift b/SmartCodable/Classes/JSONDecoder/Patcher/Patcher+Transformer.swift index 0bf7920..73eca14 100644 --- a/SmartCodable/Classes/JSONDecoder/Patcher/Patcher+Transformer.swift +++ b/SmartCodable/Classes/JSONDecoder/Patcher/Patcher+Transformer.swift @@ -9,28 +9,36 @@ import Foundation extension Patcher { struct Transformer { - static func typeTransform(from jsonValue: Any?) -> T? { + static func typeTransform(from jsonValue: JSONValue?, impl: JSONDecoderImpl) -> T? { guard let value = jsonValue else { return nil } - return (T.self as? TypeTransformable.Type)?.transformValue(from: value) as? T + return (T.self as? TypeTransformable.Type)?.transformValue(from: value, impl: impl) as? T } } } fileprivate protocol TypeTransformable { - static func transformValue(from value: Any) -> Self? + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Self? } extension Bool: TypeTransformable { - static func transformValue(from value: Any) -> Bool? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Bool? { + switch value { - case let temp as Int: - if temp == 1 { return true} - else if temp == 0 { return false } - case let temp as String: - if ["1","YES","Yes","yes","TRUE","True","true"].contains(temp) { return true } - if ["0","NO","No","no","FALSE","False","false"].contains(temp) { return false } + case .bool(let bool): + return bool + case .string(let string): + if ["1","YES","Yes","yes","TRUE","True","true"].contains(string) { return true } + if ["0","NO","No","no","FALSE","False","false"].contains(string) { return false } + case .number(let number): + if let int = try? impl.unwrapFixedWidthInteger(from: value, as: Int.self) { + if int == 1 { + return true + } else if int == 0 { + return false + } + } default: break } @@ -40,113 +48,104 @@ extension Bool: TypeTransformable { extension String: TypeTransformable { - static func transformValue(from value: Any) -> String? { - if let number = value as? NSNumber { - // Check if it's a Boolean, NSNumber is a Boolean and objCType returns "c" - if String(cString: number.objCType) == "c" { - return nil - } - } + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> String? { switch value { - case let stringValue as String: - return stringValue - case let intValue as Int: - return String(intValue) - case let floatValue as Float: - return String(floatValue) - case let doubleValue as Double: - return String(doubleValue) + case .string(let string): + return string + case .number(let number): + if let int = try? impl.unwrapFixedWidthInteger(from: value, as: Int.self) { + return "\(int)" + } else if let double = try? impl.unwrapFloatingPoint(from: value, as: Double.self) { + return "\(double)" + } + return number default: - return nil + break } + return nil } } - - - extension Int: TypeTransformable { - static func transformValue(from value: Any) -> Int? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Int? { return _fixedWidthInteger(from: value) } } extension Int8: TypeTransformable { - static func transformValue(from value: Any) -> Int8? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Int8? { return _fixedWidthInteger(from: value) } } extension Int16: TypeTransformable { - static func transformValue(from value: Any) -> Int16? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Int16? { return _fixedWidthInteger(from: value) } } extension Int32: TypeTransformable { - static func transformValue(from value: Any) -> Int32? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Int32? { return _fixedWidthInteger(from: value) } } extension Int64: TypeTransformable { - static func transformValue(from value: Any) -> Int64? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Int64? { return _fixedWidthInteger(from: value) } } extension UInt: TypeTransformable { - static func transformValue(from value: Any) -> UInt? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> UInt? { return _fixedWidthInteger(from: value) } } extension UInt8: TypeTransformable { - static func transformValue(from value: Any) -> UInt8? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> UInt8? { return _fixedWidthInteger(from: value) } } extension UInt16: TypeTransformable { - static func transformValue(from value: Any) -> UInt16? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> UInt16? { return _fixedWidthInteger(from: value) } } extension UInt32: TypeTransformable { - static func transformValue(from value: Any) -> UInt32? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> UInt32? { return _fixedWidthInteger(from: value) } } extension UInt64: TypeTransformable { - static func transformValue(from value: Any) -> UInt64? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> UInt64? { return _fixedWidthInteger(from: value) } } - - extension Float: TypeTransformable { - static func transformValue(from value: Any) -> Float? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Float? { _floatingPoint(from: value) } } extension Double: TypeTransformable { - static func transformValue(from value: Any) -> Double? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> Double? { _floatingPoint(from: value) } } extension CGFloat: TypeTransformable { - static func transformValue(from value: Any) -> CGFloat? { + static func transformValue(from value: JSONValue, impl: JSONDecoderImpl) -> CGFloat? { if let temp: Double = _floatingPoint(from: value) { return CGFloat(temp) } @@ -155,33 +154,35 @@ extension CGFloat: TypeTransformable { } -private func _floatingPoint(from value: Any) -> T? { - - // In Swift, FixedWidthInteger is a protocol that defines a set of operations and properties that are common to fixed-width integer types. - // The types that implement this protocol include all the integer types in the standard library, - // such as Int8, Int16, Int32, Int64 and their unsigned versions UInt8, UInt16, UInt32, UInt64. +private func _floatingPoint(from value: JSONValue) -> T? { switch value { - case let temp as String: - return T(temp) - case let temp as any FixedWidthInteger: - return T(temp) + case .string(let string): + return T(string) + case .number(let number): + return T(number) default: - return nil + break } + return nil } -private func _fixedWidthInteger(from value: Any) -> T? { +private func _fixedWidthInteger(from value: JSONValue) -> T? { switch value { - case let temp as String: - return T(temp) - case let temp as Float: - return T(temp) - case let temp as Double: - return T(temp) - case let temp as CGFloat: - return T(temp) + case .string(let string): + if let integer = T(string) { + return integer + } else if let float = Double(string) { + return T(float) + } + case .number(let number): + if let integer = T(number) { + return integer + } else if let float = Double(number) { + return T(float) + } default: - return nil + break } + return nil } diff --git a/SmartCodable/Classes/JSONDecoder/Patcher/Patcher.swift b/SmartCodable/Classes/JSONDecoder/Patcher/Patcher.swift index 86adff7..5bf5b11 100644 --- a/SmartCodable/Classes/JSONDecoder/Patcher/Patcher.swift +++ b/SmartCodable/Classes/JSONDecoder/Patcher/Patcher.swift @@ -13,16 +13,8 @@ struct Patcher { return try Provider.defaultValue() } - static func convertToType(from value: Any?) -> T? { - return Transformer.typeTransform(from: value) - } - - - static func patchWithConvertOrDefault(value: Any?) throws -> T { - if let value = value, let v = convertToType(from: value) { - return v - } - return try defaultForType() + static func convertToType(from value: JSONValue?, impl: JSONDecoderImpl) -> T? { + return Transformer.typeTransform(from: value, impl: impl) } }