SkillAgentSearch skills...

SmartCodable

SmartCodable is a data parsing library built on Swift’s Codable, designed for simple usage and strong real-world compatibility. It gracefully handles missing fields, default values, and evolving JSON structures. SmartCodable 是基于 Swift Codable 的数据解析库,主打简单易用与真实业务场景下的强兼容性,能够优雅应对不断变化的 JSON 数据。

Install / Use

/learn @iAmMccc/SmartCodable

README

<p align="center"> <img src="https://github.com/intsig171/SmartCodable/assets/87351449/89de27ac-1760-42ee-a680-4811a043c8b1" alt="SmartCodable" title="SmartCodable" width="500"/> </p> <h1 align="center">SmartCodable - Resilient & Flexible Codable for Swift </h1> <p align="center"> <a href="https://github.com/iAmMccc/SmartCodable/releases"> <img src="https://img.shields.io/github/v/release/iAmMccc/SmartCodable?color=blue&label=version" alt="Latest Release"> </a> <a href="https://swift.org/"> <img src="https://img.shields.io/badge/Swift-5.0%2B-orange.svg" alt="Swift 5.0+"> </a> <a href="https://github.com/iAmMccc/SmartCodable/wiki"> <img src="https://img.shields.io/badge/Documentation-available-brightgreen.svg" alt="Documentation"> </a> <a href="https://swift.org/package-manager/"> <img src="https://img.shields.io/badge/SPM-supported-DE5C43.svg?style=flat" alt="SPM Supported"> </a> <a href="https://github.com/iAmMccc/SmartCodable/blob/main/LICENSE"> <img src="https://img.shields.io/badge/license-MIT-black.svg" alt="MIT License"> </a> <a href="https://deepwiki.com/intsig171/SmartCodable"> <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"> </a> </p>

SmartCodable redefines Swift data parsing by enhancing Apple's native Codable with production-ready resilience and flexibility. It provides seamless support for default values, nested flattening, and ignored properties, reducing boilerplate while increasing reliability.

Features

Compatibility

  • Robust Parsing – Handles missing keys, type mismatches, and null values safely.
  • Safe Defaults – Falls back to property initializers when parsing fails.
  • Smart Type Conversion – Converts common types automatically (e.g., Int ⇄ String, Bool ⇄ String).

Enhancements

  • Any & Collection Support – Parses Any, [Any], [String: Any] safely.
  • Nested Path Parsing – Decode nested JSON using designated paths.
  • Custom Value Transformation – Apply transformers for advanced conversions.
  • SmartFlat Support – Flatten nested objects into parent models seamlessly.
  • SmartPublished Support – Supports ObservableObject properties with real-time updates.
  • Inheritance Support – Enables model inheritance via @SmartSubclass.
  • Stringified JSON Parsing – Converts string-encoded JSON into objects or arrays automatically.

Convenience

  • Property Ignoring – Skip specific properties with @SmartIgnored, including non-Codable fields.
  • Flexible Input Formats – Deserialize from dictionaries, arrays, JSON strings, or Data.

Callbacks

  • Post-Processing CallbackdidFinishMapping() runs after decoding for custom initialization or adjustments.

Debugging

  • SmartSentinel Logging – Real-time parsing logs to track errors and data issues.

Quick Start

import SmartCodable

struct User: SmartCodableX {
    var name: String = ""
    var age: Int = 0
}

let user = User.deserialize(from: ["name": "John", "age": 30])

Explore & Contribute

| Project / Tool | Description | | :----------------------------------------------------------- | :----------------------------------------------------------- | | 🔧 HandyJSON | Step-by-step guide to replace HandyJSON with SmartCodable in your project. | | 🛠 SmartModeler | Companion tool for converting JSON into SmartCodable Swift models. | | 👀 SmartSentinel | Real-time parsing logs to track errors and issues. Supports. | | 💖 Contributing | Support the development of SmartCodable through donations. | | 🏆 Contributors | Key contributors to the SmartCodable codebase. |

Installation

🛠 CocoaPods Installation

| Version | Installation Method | Platform Requirements | | :---------- | :--------------------------- | :----------------------------------------------------------- | | Basic | pod 'SmartCodable' | iOS 13+ tvOS 15+ macOS 10.15+ watchOS 6.0+ visionOS 1.0+ | | Inheritance | pod 'SmartCodable/Inherit' | iOS 13+ macOS 11+ |

⚠️ Important Notes:

  • If you don't have strong inheritance requirements, the basic version is recommended

  • Inheritance features require Swift Macro support, Xcode 15+, and Swift 5.9+

📌 About Swift Macros Support (CocoaPods):

  • requires downloading swift-syntax dependencies for the first time (may take longer)
  • CocoaPods internally sets user_target_xcconfig["OTHER_SWIFT_FLAGS"] to load the macro plugin during build.
  • This may affect your main target's build flags and lead to subtle differences in complex projects or CI environments.
  • If needed, please open an issue for custom setups.

📦 Swift Package Manager

dependencies: [
    .package(url: "https://github.com/iAmMccc/SmartCodable.git", from: "xxx")
]

Notes:

  • SmartCodable (runtime) works without Swift Macros.
  • SmartCodableInherit (inheritance + macros) requires Xcode 15+ and Swift 5.9+. Older SwiftPM toolchains will only expose the runtime library.

Documentation

1. The Basics

To conform to 'SmartCodable', a class need to implement an empty initializer

class BasicTypes: SmartCodableX {
    var int: Int = 2
    var doubleOptional: Double?
    required init() {}
}
let model = BasicTypes.deserialize(from: json)

For struct, since the compiler provide a default empty initializer, we use it for free.

struct BasicTypes: SmartCodableX {
    var int: Int = 2
    var doubleOptional: Double?
}
let model = BasicTypes.deserialize(from: json)

2. Deserialization API

2.1 deserialize

Only types conforming to SmartCodable (or [SmartCodable] for arrays) can use these methods

public static func deserialize(from dict: [String: Any]?, designatedPath: String? = nil,  options: Set<SmartDecodingOption>? = nil) -> Self?

public static func deserialize(from json: String?, designatedPath: String? = nil, options: Set<SmartDecodingOption>? = nil) -> Self?

public static func deserialize(from data: Data?, designatedPath: String? = nil, options: Set<SmartDecodingOption>? = nil) -> Self?

public static func deserializePlist(from data: Data?, designatedPath: String? = nil, options: Set<SmartDecodingOption>? = nil) -> Self?

1. Multi-Format Input Support

| Input Type | Example Usage | Internal Conversion | | :---------- | :------------------------------------ | :------------------------------------ | | Dictionary | Model.deserialize(from: dict) | Directly processes native collections | | Array | [Model].deserialize(from: arr) | Directly processes native collections | | JSON String | Model.deserialize(from: jsonString) | Converts to Data via UTF-8 | | Data | Model.deserialize(from: data) | Processes directly |

2. Deep Path Navigation (designatedPath)

// JSON Structure:
{
  "data": {
    "user": {
      "info": { ...target content... }
    }
  }
}

// Access nested data:
Model.deserialize(from: json, designatedPath: "data.user.info")

Path Resolution Rules:

  1. Dot-separated path components
  2. Handles both dictionaries and arrays
  3. Returns nil if any path segment is invalid
  4. Empty path returns entire content

3. Decoding Strategies (options)

let options: Set<SmartDecodingOption> = [
    .key(.convertFromSnakeCase),
    .date(.iso8601),
    .data(.base64)
]

| Strategy Type | Available Options | Description | | :----------------- | :------------------------------------ | :--------------------------- | | Key Decoding | .fromSnakeCase | snake_case → camelCase | | | .firstLetterLower | "FirstName" → "firstName" | | | .firstLetterUpper | "firstName" → "FirstName" | | Date Decoding | .iso8601, .secondsSince1970, etc. | Full Codable date strategies | | Data Decoding | .base64 | Binary data processing | | Float Decoding | .convertToString, .throw | NaN/∞ handling |

⚠️ Important: Only one strategy per type is allowed (last one wins if duplicates exist)

2.2 Post-processing callback invoked after successful decoding

struct Model: SmartCodableX {
    var name: String = ""
    
    mutating func didFinishMapping() {
        name = "I am \(name)"
    }
}

3.2 Key Transformation

Defines key mapping transformations during decoding,First non-null mapping is preferred。

static func mappingForKey() -> [SmartKeyTransformer]? {
    return [
        CodingKeys.id <--- ["user_id", "userId", "id"],
        CodingKeys.joinDate <--- "joined_at"
    ]
}

4.3 Value Transformation

Convert between JSON values and custom types

Built-in Value Transformers

| Transformer | JSON Type | Object Type | Description | | :----------------------------- | :------------ | :---------- | :----------------------------------------------------------- | | SmartDataTransformer | String | Data | Converts bet

Related Skills

View on GitHub
GitHub Stars749
CategoryDesign
Updated2d ago
Forks87

Languages

Swift

Security Score

100/100

Audited on Mar 24, 2026

No findings