{"id":28938360,"url":"https://github.com/iammccc/smartcodable","last_synced_at":"2025-12-11T22:59:18.334Z","repository":{"id":199174683,"uuid":"697569972","full_name":"iAmMccc/SmartCodable","owner":"iAmMccc","description":"SmartCodable is a data parsing library based on Codable. It is simple to use, with robust compatibility being one of its main features. SmartCodable 是基于Codable实现的数据解析库。简单易用，强悍的兼容性是SmartCodable的主要特点。  表层API和功能几乎和HandyJSON一致，支持快速的迁移。","archived":false,"fork":false,"pushed_at":"2025-06-18T10:07:43.000Z","size":8748,"stargazers_count":611,"open_issues_count":1,"forks_count":65,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-06-18T10:18:35.625Z","etag":null,"topics":["codable","handyjson","json","mapping","metacodable","serialization","swift","swift-codable","swift-syntax-builder"],"latest_commit_sha":null,"homepage":"https://smart-codable.vercel.app","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iAmMccc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-28T02:34:03.000Z","updated_at":"2025-06-18T10:07:34.000Z","dependencies_parsed_at":"2023-11-24T05:20:48.341Z","dependency_job_id":"b41f4e6c-e673-4b0a-b07e-5c637ff49d81","html_url":"https://github.com/iAmMccc/SmartCodable","commit_stats":null,"previous_names":["intsig171/smartcodable","iammccc/smartcodable"],"tags_count":120,"template":false,"template_full_name":null,"purl":"pkg:github/iAmMccc/SmartCodable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iAmMccc%2FSmartCodable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iAmMccc%2FSmartCodable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iAmMccc%2FSmartCodable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iAmMccc%2FSmartCodable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iAmMccc","download_url":"https://codeload.github.com/iAmMccc/SmartCodable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iAmMccc%2FSmartCodable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261380466,"owners_count":23149934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codable","handyjson","json","mapping","metacodable","serialization","swift","swift-codable","swift-syntax-builder"],"created_at":"2025-06-22T22:41:01.904Z","updated_at":"2025-12-11T22:59:18.328Z","avatar_url":"https://github.com/iAmMccc.png","language":"Swift","readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/intsig171/SmartCodable/assets/87351449/89de27ac-1760-42ee-a680-4811a043c8b1\" alt=\"SmartCodable\" title=\"SmartCodable\" width=\"500\"/\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eSmartCodable - Ultimate Codable Enhancement for Swift\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/iAmMccc/SmartCodable/releases\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/v/release/iAmMccc/SmartCodable?color=blue\u0026label=version\" alt=\"Latest Release\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/iAmMccc/SmartCodable/actions\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/iAmMccc/SmartCodable/swift.yml?branch=main\u0026label=build%20status\u0026logo=github\" alt=\"Build Status\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/iAmMccc/SmartCodable/wiki\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Documentation-available-brightgreen.svg\" alt=\"Documentation\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://swift.org/package-manager/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat\" alt=\"SPM Supported\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://swift.org/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift-5.0%2B-orange.svg\" alt=\"Swift 5.0+\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://www.apple.com/swift/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/platform-iOS%2FmacOS%2FtvOS%2FwatchOS-blue.svg\" alt=\"Platform Support\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/iAmMccc/SmartCodable/graphs/contributors\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/contributors/iAmMccc/SmartCodable\" alt=\"Contributors\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/iAmMccc/SmartCodable/blob/main/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-MIT-black.svg\" alt=\"MIT License\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://deepwiki.com/intsig171/SmartCodable\"\u003e\n    \u003cimg src=\"https://deepwiki.com/badge.svg\" alt=\"Ask DeepWiki\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\n### English | [中文](https://github.com/iAmMccc/SmartCodable/blob/main/README_CN.md)\n\n\n\nSmartCodable redefines Swift data parsing by augmenting Apple's native Codable with production-ready resilience and flexibility. Where standard Codable fails on real-world data, SmartCodable delivers bulletproof parsing with minimal boilerplate.\n\n## **SmartCodable vs Codable**\n\n| 🎯 Feature                  | 💬 Description                                                |\n| :------------------------- | :----------------------------------------------------------- |\n| **Error Tolerance**        | Military-grade handling of type mismatches, null values, and missing keys |\n| **Type Adaptation**        | Automatic bidirectional type conversion (String⇄Number, Number⇄Bool, etc.) |\n| **Default Value Fallback** | Falls back to property initializers when parsing fails       |\n| **Support inheritance**    | Barrier-free support for inheritance                         |\n| **Key Mapping**            | Multi-source key mapping with priority system                |\n| **Value Transformation**   | Custom value transformers                                    |\n| **Collection Safety**      | Safe collection handling (empty arrays→nil, invalid elements→filtered) |\n| **Deep Modelization**      | Recursive modelization of nested JSON structures             |\n| **Dynamic Types**          | Full support for `Any`, `[Any]`, `[String:Any]` via `@SmartAny` |\n| **Naming Strategies**      | Global key strategies (snake_case⇄camelCase, capitalization) |\n| **Lifecycle Hooks**        | `didFinishMapping()` callback for post-processing            |\n| **Incremental Updates**    | Partial model updates without full re-parsing                |\n| **Property Wrappers**      | such as`@IgnoredKey`, `@SmartFlat`,`@SmartAny`               |\n| **Debugging Support**      | Built-in logging with path tracing for decoding errors       |\n| **Path Navigation**        | Deep JSON access using dot notation (`designatedPath: \"data.user\"`) |\n| **PropertyList Support**   | Native support for parsing PropertyList data without JSON conversion |\n| **Parsing Diagnostics**    | Real-time monitoring with `SmartSentinel.monitorLogs()`      |\n\n\n\n## SmartCodable vs HandyJSON \n\n| 🎯 Feature                              | 💬 Description                                                | SmartCodable | HandyJSON |\n| :------------------------------------- | :----------------------------------------------------------- | :----------- | :-------- |\n| **Strong Compatibility**               | Perfectly handles: **Missing fields** \u0026 **Null values** \u0026 **Type mismatches** | ✅            | ✅         |\n| **Type Adaptation**                    | Automatic conversion between types (e.g., JSON Int to Model String) | ✅            | ✅         |\n| **Any Parsing**                        | Supports parsing **[Any], [String: Any]** types              | ✅            | ✅         |\n| **Decoding Callback**                  | Provides **didFinishingMapping** callback when model decoding completes | ✅            | ✅         |\n| **Default Value Initialization**       | Uses property's initial value when parsing fails             | ✅            | ✅         |\n| **String-to-Model Parsing**            | Supports parsing JSON strings into models                    | ✅            | ✅         |\n| **Enum Parsing**                       | Provides fallback for failed enum parsing                    | ✅            | ✅         |\n| **Custom Property Parsing - Renaming** | Custom decoding keys (renaming model properties)             | ✅            | ✅         |\n| **Custom Property Parsing - Ignoring** | Ignores specific model properties during decoding            | ✅            | ✅         |\n| **designatedPath Support**             | Custom parsing paths                                         | ✅            | ✅         |\n| **Model Inheritance**                  | Use `@SmartSubclass` to modify the Model                     | ✅            | ✅         |\n| **Custom Parsing Paths**               | Specifies starting JSON hierarchy level for parsing          | ✅            | ✅         |\n| **Complex Data Decoding**              | Advanced data processing during decoding (e.g., data flattening) | ✅            | ⚠️         |\n| **Decoding Performance**               | SmartCodable averages 20% better performance                 | ✅            | ⚠️         |\n| **Error Logging**                      | Provides troubleshooting logs for compatibility handling     | ✅            | ❌         |\n| **Security**                           | Implementation stability and security                        | ✅            | ❌         |\n\nIf you are using HandyJSON and would like to replace it, follow this link.\n\n [👉 **SmartCodable - Compare With HandyJSON**](https://github.com/iAmMccc/SmartCodable/blob/main/Document/README/CompareWithHandyJSON.md)\n\n**Key Advantages**:\n\n- 20% better performance\n- More stable and secure implementation\n- Built-in error diagnostics\n- Superior complex data handling\n\n\n\n## SmartCodable Supported Types Comparison\n\n| Type               | Examples                              |\n| :----------------- | :------------------------------------ |\n| **Integer**        | `Int`, `Int8-64`, `UInt`, `UInt8-64`  |\n| **Floating Point** | `Float`, `Double`, `CGFloat`          |\n| **Boolean**        | `Bool` (accepts `true`/`1`/`\"true\"`)  |\n| **String**         | `String` (auto-converts from numbers) |\n| **Foundation**     | `URL`, `Date`, `Data`, `UIColor`      |\n| **Enums**          | All `RawRepresentable` enums          |\n| **Collections**    | `[String: Codable]`, `[Codable]`      |\n| **Nested Models**  | Any `Codable` custom types            |\n| **Wrappers**       | `@SmartAny`, `@IgnoredKey`, etc.      |\n\n## Installation\n\n### 🛠 CocoaPods Installation\n\n| Version     | Installation Method          | Platform Requirements                                        |\n| :---------- | :--------------------------- | :----------------------------------------------------------- |\n| Basic       | `pod 'SmartCodable'`         | `iOS 13+` `tvOS 15+` `macOS 10.15+` `watchOS 6.0+` `visionOS 1.0+` |\n| Inheritance | `pod 'SmartCodable/Inherit'` | `iOS 13+` `macOS 11+`                                        |\n\n⚠️ **Important Notes**:\n\n- If you don't have strong inheritance requirements, the basic version is recommended\n\n- Inheritance features require **Swift Macro support**, **Xcode 15+**, and **Swift 5.9+**\n\n  \n\n  \n\n📌 **About Swift Macros Support (CocoaPods)**:\n\n* requires downloading `swift-syntax` dependencies for the first time (may take longer)\n* CocoaPods internally sets `user_target_xcconfig[\"OTHER_SWIFT_FLAGS\"]` to load the macro plugin during build.\n* This may affect your main target's build flags and lead to subtle differences in complex projects or CI environments.\n* If needed, please [open an issue](https://github.com/iAmMccc/SmartCodable/issues) for custom setups.\n\n\n\n### 📦 Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/iAmMccc/SmartCodable.git\", from: \"xxx\")\n]\n```\n\n\n\n### Usage Examples\n\n```swift\nimport SmartCodable\n\nstruct User: SmartCodable {\n    var name: String = \"\"\n    var age: Int = 0\n}\nlet user = User.deserialize(from: [\"name\": \"John\", \"age\": 30])\n```\n\n\n\n# Deserialization\n\nTo support deserialization from JSON, a class/struct need to conform to 'SmartCodable' protocol. \n\n### 1. The Basics\n\nTo conform to 'SmartCodable', a class need to implement an empty initializer.\n\n```swift\nclass BasicTypes: SmartCodable {\n    var int: Int = 2\n    var doubleOptional: Double?\n    required init() {}\n}\nlet model = BasicTypes.deserialize(from: json)\n```\n\nFor struct, since the compiler provide a default empty initializer, we use it for free.\n\n```swift\nstruct BasicTypes: SmartCodable {\n    var int: Int = 2\n    var doubleOptional: Double?\n}\nlet model = BasicTypes.deserialize(from: json)\n```\n\n\n\n### 2. Deserialization API\n\n#### 2.1 deserialize\n\nOnly types conforming to `SmartCodable` (or `[SmartCodable]` for arrays) can use these methods\n\n```swift\npublic static func deserialize(from dict: [String: Any]?, designatedPath: String? = nil,  options: Set\u003cSmartDecodingOption\u003e? = nil) -\u003e Self?\n\npublic static func deserialize(from json: String?, designatedPath: String? = nil, options: Set\u003cSmartDecodingOption\u003e? = nil) -\u003e Self?\n\npublic static func deserialize(from data: Data?, designatedPath: String? = nil, options: Set\u003cSmartDecodingOption\u003e? = nil) -\u003e Self?\n\npublic static func deserializePlist(from data: Data?, designatedPath: String? = nil, options: Set\u003cSmartDecodingOption\u003e? = nil) -\u003e Self?\n```\n\n**1. Multi-Format Input Support**\n\n| Input Type       | Example Usage                          | Internal Conversion                   |\n| :--------------- | :------------------------------------- | :------------------------------------ |\n| Dictionary/Array | `Model.deserialize(from: dict or arr)` | Directly processes native collections |\n| JSON String      | `Model.deserialize(from: jsonString)`  | Converts to `Data` via UTF-8          |\n| Binary Data      | `Model.deserialize(from: data)`        | Processes directly                    |\n\n**2. Deep Path Navigation (`designatedPath`)**\n\n```\n// JSON Structure:\n{\n  \"data\": {\n    \"user\": {\n      \"info\": { ...target content... }\n    }\n  }\n}\n\n// Access nested data:\nModel.deserialize(from: json, designatedPath: \"data.user.info\")\n```\n\n**Path Resolution Rules:**\n\n1. Dot-separated path components\n2. Handles both dictionaries and arrays\n3. Returns `nil` if any path segment is invalid\n4. Empty path returns entire content\n\n**3. Decoding Strategies (`options`)**\n\n```swift\nlet options: Set\u003cSmartDecodingOption\u003e = [\n    .key(.convertFromSnakeCase),\n    .date(.iso8601),\n    .data(.base64)\n]\n```\n\n| Strategy Type      | Available Options                     | Description                  |\n| :----------------- | :------------------------------------ | :--------------------------- |\n| **Key Decoding**   | `.fromSnakeCase`                      | snake_case → camelCase       |\n|                    | `.firstLetterLower`                   | \"FirstName\" → \"firstName\"    |\n|                    | `.firstLetterUpper`                   | \"firstName\" → \"FirstName\"    |\n| **Date Decoding**  | `.iso8601`, `.secondsSince1970`, etc. | Full Codable date strategies |\n| **Data Decoding**  | `.base64`                             | Binary data processing       |\n| **Float Decoding** | `.convertToString`, `.throw`          | NaN/∞ handling               |\n\n\u003e ⚠️ **Important**: Only one strategy per type is allowed (last one wins if duplicates exist)\n\n\n\n#### 2.2 Post-processing callback invoked after successful decoding\n\n```swift\nstruct Model: SmartCodable {\n    var name: String = \"\"\n    \n    mutating func didFinishMapping() {\n        name = \"I am \\(name)\"\n    }\n}\n```\n\n\n\n#### 3.2 Key Transformation\n\nDefines key mapping transformations during decoding，First non-null mapping is preferred。\n\n```swift\nstatic func mappingForKey() -\u003e [SmartKeyTransformer]? {\n    return [\n        CodingKeys.id \u003c--- [\"user_id\", \"userId\", \"id\"],\n        CodingKeys.joinDate \u003c--- \"joined_at\"\n    ]\n}\n```\n\n\n\n#### 4.3 **Value Transformation**\n\nConvert between JSON values and custom types\n\n**Built-in Value Transformers**\n\n| Transformer                    | JSON Type     | Object Type | Description                                                  |\n| :----------------------------- | :------------ | :---------- | :----------------------------------------------------------- |\n| **SmartDataTransformer**       | String        | Data        | Converts between Base64 strings and Data objects             |\n| **SmartHexColorTransformer**   | String        | ColorObject | Converts hex color strings to platform-specific color objects (UIColor/NSColor) |\n| **SmartDateTransformer**       | Double/String | Date        | Handles multiple date formats (timestamp Double or String) to Date objects |\n| **SmartDateFormatTransformer** | String        | Date        | Uses DateFormatter for custom date string formats            |\n| **SmartURLTransformer**        | String        | URL         | Converts strings to URLs with optional encoding and prefixing |\n\n```swift\nstruct Model: SmartCodable {\n    \n    ...\n    \n    static func mappingForValue() -\u003e [SmartValueTransformer]? {\n        let format = DateFormatter()\n        format.dateFormat = \"yyyy-MM-dd\"\n        return [\n            CodingKeys.url \u003c--- SmartURLTransformer(prefix: \"https://\"),\n            CodingKeys.date2 \u003c--- SmartDateTransformer(),\n            CodingKeys.date1 \u003c--- SmartDateFormatTransformer(format)\n        ]\n    }\n}\n```\n\nIf you need additional parsing rules, **Transformer** will implement them yourself. Follow **ValueTransformable** to implement the requirements of the protocol.\n\n```swift\npublic protocol ValueTransformable {\n    associatedtype Object\n    associatedtype JSON\n    \n    /// transform from ’json‘ to ’object‘\n    func transformFromJSON(_ value: Any?) -\u003e Object?\n    \n    /// transform to ‘json’ from ‘object’\n    func transformToJSON(_ value: Object?) -\u003e JSON?\n}\n```\n\n**Built-in Fast Transformer Helper**\n\n```swift\nstatic func mappingForValue() -\u003e [SmartValueTransformer]? {\n    [\n        CodingKeys.name \u003c--- FastTransformer\u003cString, String\u003e(fromJSON: { json in\n            \"abc\"\n        }, toJSON: { object in\n            \"123\"\n        }),\n        CodingKeys.subModel \u003c--- FastTransformer\u003cTestEnum, String\u003e(fromJSON: { json in\n            TestEnum.man\n        }, toJSON: { object in\n            object?.rawValue\n        }),\n    ]\n}\n```\n\n\n\n\n\n\n### 3. propertyWrapper\n\n#### 3.1 @SmartAny\n\nCodable does not support Any resolution, but can be implemented using @SmartAny。\n\n```swift\nstruct Model: SmartCodable {\n    @SmartAny var dict: [String: Any] = [:]\n    @SmartAny var arr: [Any] = []\n    @SmartAny var any: Any?\n}\nlet dict: [String: Any] = [\n    \"dict\": [\"name\": \"Lisa\"],\n    \"arr\": [1,2,3],\n    \"any\": \"Mccc\"\n]\n\nlet model = Model.deserialize(from: dict)\nprint(model)\n// Model(dict: [\"name\": \"Lisa\"], arr: [1, 2, 3], any: \"Mccc\")\n```\n\n\n\n#### 3.2 @IgnoredKey\n\nIf you need to ignore the parsing of attributes, you can override `CodingKeys` or use `@IgnoredKey`.\n\n```swift\nstruct Model: SmartCodable {\n    @IgnoredKey\n    var name: String = \"\"\n}\n\nlet dict: [String: Any] = [\n    \"name\": \"Mccc\"\n]\n\nlet model = Model.deserialize(from: dict)\nprint(model)\n// Model(name: \"\")\n```\n\n\n\n#### 3.3 @SmartFlat\n\n```swift\nstruct Model: SmartCodable {\n    var name: String = \"\"\n    var age: Int = 0\n  \n    @SmartFlat\n    var model: FlatModel?\n   \n}\nstruct FlatModel: SmartCodable {\n    var name: String = \"\"\n    var age: Int = 0\n}\n\nlet dict: [String: Any] =  [\n    \"name\": \"Mccc\",\n    \"age\": 18,\n]\n\nlet model = Model.deserialize(from: dict)\nprint(model)\n// Model(name: \"Mccc\", age: 18, model: FlatModel(name: \"Mccc\", age: 18))\n```\n\n\n\n#### 3.4 @SmartPublished\n\n```swift\nclass PublishedModel: ObservableObject, SmartCodable {\n    required init() {}\n    \n    @SmartPublished\n    var name: ABC?\n}\n\nstruct ABC: SmartCodable {\n    var a: String = \"\"\n}\n\nif let model = PublishedModel.deserialize(from: dict) {\n    model.$name\n        .sink { newName in\n            print(\"name updated，newValue is: \\(newName)\")\n        }\n        .store(in: \u0026cancellables)\n}\n```\n\n#### 3.5 @SmartHexColor\n\nAdds Codable support for UIColor/NSColor using hex string encoding/decoding.\n\n```swift\nstruct Model: SmartCodable {\n    @SmartHexColor\n    var color: UIColor?\n}\n\nlet dict: [String: Any] = [\n    \"color\": \"7DA5E3\"\n]\n\nlet model = Model.deserialize(from: dict)\nprint(model)\n// print: Model(color: UIExtendedSRGBColorSpace 0.490196 0.647059 0.890196 1)\n```\n\n\n\n### 4. Inheritance Support\n\nThis feature relies on **Swift Macros**, which requires **Swift 5.9+** and is compatible with **iOS 13+**. Therefore, it is only supported in SmartCodable version 5.0 and above.\n\n\u003e For using inheritance on lower versions, refer to: [Inheritance in Lower Versions](https://github.com/iAmMccc/SmartCodable/blob/main/Document/QA/QA2.md)\n\nIf you need inheritance support, annotate your subclass with `@SmartSubclass`.\n\n#### 4.1 Basic Usage\n\n```swift\nclass BaseModel: SmartCodable {\n    var name: String = \"\"\n    required init() { }\n}\n\n@SmartSubclass\nclass StudentModel: BaseModel {\n    var age: Int?\n}\n```\n\n#### 4.2 Subclass Implements Protocol Method\n\nJust implement it directly—no need for the `override` keyword.\n\n```swift\nclass BaseModel: SmartCodable {\n    var name: String = \"\"\n    required init() { }\n    \n    class func mappingForKey() -\u003e [SmartKeyTransformer]? {\n        retrun nil\n    }\n}\n\n@SmartSubclass\nclass StudentModel: BaseModel {\n    var age: Int?\n    \n    override static func mappingForKey() -\u003e [SmartKeyTransformer]? {\n        [ CodingKeys.age \u003c--- \"stu_age\" ]\n    }\n}\n```\n\n#### 4.3 Parent Class Implements Protocol Method\n\n```swift\nclass BaseModel: SmartCodable {\n    var name: String = \"\"\n    required init() { }\n    \n    static func mappingForKey() -\u003e [SmartKeyTransformer]? {\n        [ CodingKeys.name \u003c--- \"stu_name\" ]\n    }\n}\n\n@SmartSubclass\nclass StudentModel: BaseModel {\n    var age: Int?\n}\n```\n\n#### 4.4 Both Parent and Subclass Implement Protocol Method\n\nA few things to note:\n\n- The protocol method in the parent class must be marked with `class`.\n- The subclass should call the parent class's implementation.\n\n```swift\nclass BaseModel: SmartCodable {\n    var name: String = \"\"\n    required init() { }\n    \n    class func mappingForKey() -\u003e [SmartKeyTransformer]? {\n        [ CodingKeys.name \u003c--- \"stu_name\" ]\n    }\n}\n\n@SmartSubclass\nclass StudentModel: BaseModel {\n    var age: Int?\n    \n    override static func mappingForKey() -\u003e [SmartKeyTransformer]? {\n        let trans = [ CodingKeys.age \u003c--- \"stu_age\" ]\n        \n        if let superTrans = super.mappingForKey() {\n            return trans + superTrans\n        } else {\n            return trans\n        }\n    }\n}\n```\n\n\n\n### 5. Special support\n\n#### 5.1 Smart Stringified JSON Parsing\n\nSmartCodable automatically handles string-encoded JSON values during decoding, seamlessly converting them into nested model objects or arrays while maintaining all key mapping rules.\n\n- **Automatic Parsing**: Detects and decodes stringified JSON (`\"{\\\"key\\\":value}\"`) into proper objects/arrays\n- **Recursive Mapping**: Applies `mappingForKey()` rules to parsed nested structures\n- **Type Inference**: Determines parsing strategy (object/array) based on property type\n\n```swift\nstruct Model: SmartCodable {\n    var hobby: Hobby?\n    var hobbys: [Hobby]?\n}\n\nstruct Hobby: SmartCodable {\n    var name: String = \"\"\n}\n\nlet dict: [String: Any] = [\n    \"hobby\": \"{\\\"name\\\":\\\"sleep1\\\"}\",\n    \"hobbys\": \"[{\\\"name\\\":\\\"sleep2\\\"}]\",\n]\n\nguard let model = Model.deserialize(from: dict) else { return }\n```\n\n\n\n#### 5.2 Compatibility\n\nIf attribute resolution fails, SmartCodable performs compatibility processing for thrown exceptions. Ensure that the entire parsing is not interrupted. Even better, you don't have to do anything about it.\n\n```swift\nlet dict = [\n    \"number1\": \"123\",\n    \"number2\": \"Mccc\",\n    \"number3\": \"Mccc\"\n]\n\nstruct Model: SmartCodable {\n    var number1: Int?\n    var number2: Int?\n    var number3: Int = 1\n}\n\n// decode result\n// Model(number1: 123, number2: nil, number3: 1)\n```\n\n**Type conversion compatibility**\n\nWhen the data is parsed, the type cannot be matched. Raises a.typeMismatch error. SmartCodable will attempt to convert data of type String to the desired type Int.\n\n**Default Fill compatible**\n\nWhen the type conversion fails, the initialization value of the currently parsed property is retrieved for padding.\n\n#### 5.3 parse very large data\n\nWhen you parse very large data, try to avoid the compatibility of parsing exceptions, such as: more than one attribute is declared in the attribute, and the declared attribute type does not match. \n\nDo not use @IgnoredKey when there are attributes that do not need to be parsed, override CodingKeys to ignore unwanted attribute parsing. \n\nThis can greatly improve the analytical efficiency.\n\n\n\n#### 5.4 The Enum\n\nTo be convertable, An `enum` must conform to `SmartCaseDefaultable` protocol. Nothing special need to do now.\n\n```swift\nstruct Student: SmartCodable {\n    var name: String = \"\"\n    var sex: Sex = .man\n\n    enum Sex: String, SmartCaseDefaultable {\n        case man = \"man\"\n        case woman = \"woman\"\n    }\n}\nlet model = Student.deserialize(from: json)\n```\n\n\n\n**Decoding of associative value enum**\n\nMake the enumeration follow **SmartAssociatedEnumerable**。Override the **mappingForValue** method and take over the decoding process yourself.\n\n```swift\nstruct Model: SmartCodable {\n    var sex: Sex = .man\n    static func mappingForValue() -\u003e [SmartValueTransformer]? {\n        [\n            CodingKeys.sex \u003c--- RelationEnumTranformer()\n        ]\n    }\n}\n\nenum Sex: SmartAssociatedEnumerable {    \n    case man\n    case women\n    case other(String)\n}\n\nstruct RelationEnumTranformer: ValueTransformable {\n    typealias Object = Sex\n    typealias JSON = String\n\n    func transformToJSON(_ value: Introduce_8ViewController.Sex?) -\u003e String? {\n        // do something\n    }\n    func transformFromJSON(_ value: Any?) -\u003e Sex? {\n        // do something\n    }\n}\n```\n\n\n\n#### 5.5 Update Existing Model\n\nIt can accommodate any data structure, including nested array structures.\n\n```swift\nstruct Model: SmartCodable {\n    var name: String = \"\"\n    var age: Int = 0\n}\n\nvar dic1: [String : Any] = [\n    \"name\": \"mccc\",\n    \"age\": 10\n]\nlet dic2: [String : Any] = [\n    \"age\": 200\n]\nguard var model = Model.deserialize(from: dic1) else { return }\nSmartUpdater.update(\u0026model, from: dic2)\n\n// now: model is [\"name\": mccc, \"age\": 200].\n```\n\n\n\n\n\n## **Sentinel** \n\nSmartCodable is integrated with Smart Sentinel, which listens to the entire parsing process. After the parsing is complete, formatted log information is displayed. \n\nThis information is used only as auxiliary information to help you discover and rectify problems. This does not mean that the parsing failed.\n\n```\n================================  [Smart Sentinel]  ================================\nArray\u003cSomeModel\u003e 👈🏻 👀\n   ╆━ Index 0\n      ┆┄ a: Expected to decode 'Int' but found ‘String’ instead.\n      ┆┄ b: Expected to decode 'Int' but found ’Array‘ instead.\n      ┆┄ c: No value associated with key.\n      ╆━ sub: SubModel\n         ┆┄ sub_a: No value associated with key.\n         ┆┄ sub_b: No value associated with key.\n         ┆┄ sub_c: No value associated with key.\n      ╆━ sub2s: [SubTwoModel]\n         ╆━ Index 0\n            ┆┄ sub2_a: No value associated with key.\n            ┆┄ sub2_b: No value associated with key.\n            ┆┄ sub2_c: No value associated with key.\n         ╆━ Index 1\n            ┆┄ sub2_a: Expected to decode 'Int' but found ’Array‘ instead.\n   ╆━ Index 1\n      ┆┄ a: No value associated with key.\n      ┆┄ b: Expected to decode 'Int' but found ‘String’ instead.\n      ┆┄ c: Expected to decode 'Int' but found ’Array‘ instead.\n      ╆━ sub: SubModel\n         ┆┄ sub_a: Expected to decode 'Int' but found ‘String’ instead.\n      ╆━ sub2s: [SubTwoModel]\n         ╆━ Index 0\n            ┆┄ sub2_a: Expected to decode 'Int' but found ‘String’ instead.\n         ╆━ Index 1\n            ┆┄ sub2_a: Expected to decode 'Int' but found 'null' instead.\n====================================================================================\n```\n\nIf you want to use it, turn it on:\n\n```swift\nSmartSentinel.debugMode = .verbose\npublic enum Level: Int {\n    case none\n    case verbose\n    case alert\n}\n```\n\nIf you want to get this log to upload to the server:\n\n```swift\nSmartSentinel.onLogGenerated { logs in  }\n```\n\n\n## SmartModeler - JSON To Swift SmartCodable Tool\n\n[online access](https://iammccc.github.io)\n![](https://github.com/iAmMccc/iAmMccc.github.io/blob/main/演示图.png)\n\n\n## FAQ\n\nIf you're looking forward to learning more about the Codable protocol and the design thinking behind SmartCodable, check it out.\n\n[👉 **github discussions**](https://github.com/iAmMccc/SmartCodable/discussions)\n\n[👉 **SmartCodable Test**](https://github.com/iAmMccc/SmartCodable/blob/main/Document/README/HowToTest.md)\n\n[👉 **learn SmartCodable**](https://github.com/iAmMccc/SmartCodable/blob/main/Document/README/LearnMore.md)\n\n\n\n## Github Stars\n![GitHub stars](https://starchart.cc/iAmMccc/SmartCodable.svg)\n\n## Join the SmartCodable Community 🚀\n\nSmartCodable is an open-source project dedicated to making Swift data parsing more robust, flexible and efficient. We welcome all developers to join our community!\n\n\n![JoinUs](https://github.com/user-attachments/assets/7b1f8108-968e-4a38-91dd-b99abdd3e500)\n\n\n\n## Support 💖\n\n![Support](https://github.com/iAmMccc/SmartCodable/blob/main/Document/support.png)\n\n\n\n### [💖Contributing💖](https://github.com/iAmMccc/SmartCodable/blob/main/Contributing/ContributingList.md)\n\n## License\n\nSmartCodable is available under the MIT license. See the LICENSE file for more info.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiammccc%2Fsmartcodable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiammccc%2Fsmartcodable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiammccc%2Fsmartcodable/lists"}