@@ -9,14 +9,20 @@ configuration files, feature flags, and analytics payloads.
99
1010## β¨ Why DynamicJSON?
1111
12- Modern APIs often return unpredictable or inconsistently formatted JSON:
12+ Working with JSON in Swift can be painful β especially when the structure is inconsistent,
13+ values are loosely typed, or keys are formatted in unpredictable ways.
1314
14- - Keys can be in ` camelCase ` , ` snake_case ` , ` kebab-case ` , or ` ALLCAPS `
15- - Values might be ` "true" ` instead of ` true ` , ` "1" ` instead of ` 1 `
16- - Dates may be strings, numbers (timestamps) , or malformed
17- - You might receive ` "enabled" ` , ` "yes" ` , ` 1 ` , or ` true ` for the same toggle
15+ - Some keys are ` camelCase ` , others are ` snake_case ` , or even ` ALLCAPS `
16+ - Values might be ` "true" ` , ` true ` , ` "1" ` , ` 1 ` , or ` "yes" ` β all meaning the same thing
17+ - Dates can show up in a dozen formats , or even as raw timestamps
18+ - Typos happen β from backend devs or third-party APIs
1819
19- ` DynamicJSON ` makes handling all of this effortless with:
20+ Thatβs where ` DynamicJSON ` comes in. Itβs a smart, forgiving, and developer-friendly way
21+ to decode and work with dynamic JSON data. Whether you're pulling feature flags,
22+ remote config, analytics events, or responses from external APIs
23+ ` DynamicJSON ` makes it all seamless.
24+
25+ ` DynamicJSON ` handles all of this for you β so you donβt have to write dozens of if-lets, custom decoders, or fail silently.
2026
2127β
Normalized key lookup
2228β
Fuzzy match for typos and partial keys
@@ -25,35 +31,58 @@ Modern APIs often return unpredictable or inconsistently formatted JSON:
2531β
Dynamic member syntax (` json.user.name ` )
2632β
Type-safe ` .as() ` casting method
2733
34+ in other words, you ask for what you want, and it finds it β no matter how the data was sent.
35+
2836---
2937
3038## π‘ Key Use Cases
3139
32- - Feature flag systems
33- - API responses with evolving schemas
34- - Third-party JSON data ingestion
35- - Analytics payloads and event tracking
36- - Backend-driven UI toggles
37- - Configuration files
40+ - π§ Feature flag systems where keys may be inconsistent or added dynamically
41+ - π¦ Remote configuration delivery (AB testing, UI settings, runtime tuning)
42+ - π Analytics and event tracking systems that send flexible JSON payloads
43+ - π APIs that return unpredictable or evolving response schemas
44+ - π Third-party integrations where key names and formats canβt be controlled
45+ - π Legacy systems with inconsistent formatting and naming conventions
46+ - π§ͺ Testing tools that need to mock flexible or partial JSON payloads
47+ - βοΈ Backend-driven UI state (e.g., hiding/showing features remotely)
48+ - π JSON-based configuration files or local overrides in development builds
49+ - π§΅ Telemetry logs and diagnostic data where key/value shape varies per device
3850
3951---
4052
4153## π¦ Installation
4254
4355``` swift
44- .package (url : " https://github.com/yourusername/DynamicFeatureFlag.git" , from : " 1.0.0" )
56+ .package (url : " https://github.com/ihamadfouad/DynamicJSON-SDK.git" , from : " 1.0.0" )
57+
58+ import DynamicJSON
59+
4560```
4661
4762## β
Features Overview
4863
49- Feature |Example
50- ----------------
51- Dot-path access | json[ "user.settings.notifications.email"]
52- Dynamic member lookup | json.user.settings.notifications.email
53- Subscript with normalization | json[ "UserSettings"] == json.user_settings
54- Case-insensitive + format-tolerant | "Feature_Toggle" == "featureToggle"
55- Fuzzy key match (typo-tolerant) | "featurTogle" β "feature_toggle"
56- Partial match support | "beta" β "beta_feature_x"
64+ | Category | Feature | Example or Notes |
65+ | --------------------| -------------------------------------------------------------------------| ------------------------------------------------------------------|
66+ | π Key Access | Dot-path access | ` json["user.settings.notifications.email"] ` |
67+ | | Dynamic member access | ` json.user.settings.notifications.email ` |
68+ | | Subscript with format normalization | ` json["UserSettings"] == json.user_settings ` |
69+ | | Case-insensitive and format-tolerant key matching | Matches camelCase, snake_case, kebab-case, etc. |
70+ | | Fuzzy key matching (typo-tolerant) | ` "featurTogle" ` β ` "feature_toggle" ` |
71+ | | Partial key match support | ` "beta" ` β ` "beta_feature_x" ` |
72+ | | Auto-normalized lookup for deep and flat structures | Works seamlessly at any nesting depth |
73+ | π Type Conversion | Boolean from string/number/words | ` "true" ` , ` "yes" ` , ` "1" ` , ` 1 ` , etc. |
74+ | | Integer parsing from string, float, bool | ` "25" ` , ` 25.0 ` , ` true ` |
75+ | | Double parsing from string/int/bool | ` "12.5" ` , ` 1 ` , ` true ` |
76+ | | String coercion from bool, number | ` true ` β ` "true" ` , ` 42.0 ` β ` "42" ` |
77+ | | Date parsing from multiple formats | ISO8601, MySQL, RFC3339, short, timestamps |
78+ | | Generic ` .as(T.self) ` casting | ` json["key"].as(Int.self) ` |
79+ | π§© JSON Structure | ` .array ` to unwrap JSON arrays | Returns ` [DynamicJSON]? ` |
80+ | | ` .dictionary ` to unwrap objects | Returns ` [String: DynamicJSON]? ` |
81+ | | ` .isNull ` to check for ` null ` or missing values | Returns ` true ` if ` null ` or nonexistent |
82+ | π Developer Tools | Logs fuzzy/partial matches with warnings | Helpful for debugging mismatches |
83+ | | Gracefully returns ` .null ` instead of crashing on access | Safe fallback handling |
84+ | π Use Flexibility | Works with deeply nested and mixed-type JSON | Great for dynamic payloads |
85+ | | Handles inconsistent or unpredictable backends | Makes JSON-safe across the board |
5786
5887# π Usage Example
5988
@@ -88,22 +117,22 @@ let pushOn = json["settings.notifications.push"].bool // false
88117## π§ Smart Key Matching
89118
90119DynamicJSON will normalize and match keys like:
91- β’ "FeatureToggle" β "feature_toggle"
92- β’ "darkMode" β "dark_mode"
93- β’ "beta-feature-x" β "beta_feature_x"
94- β’ "FEATURETOGGLE" β "feature_toggle"
95- β’ "featurTogle" β fuzzy match β "feature_toggle"
120+ β’ "FeatureToggle" β "feature_toggle"
121+ β’ "darkMode" β "dark_mode"
122+ β’ "beta-feature-x" β "beta_feature_x"
123+ β’ "FEATURETOGGLE" β "feature_toggle"
124+ β’ "featurTogle" β fuzzy match β "feature_toggle"
96125
97126π
Date Parsing
98127
99128Supports:
100- β’ 2024-01-01T12:34:56Z
101- β’ 2024-01-01T12:34:56.123Z
102- β’ 2024-01-01 12:34:56
103- β’ 2024-01-01
104- β’ 01/01/2024
105- β’ 01-01-2024
106- β’ UNIX timestamp: 1704067200 or 1704067200000
129+ β’ 2024-01-01T12:34:56Z
130+ β’ 2024-01-01T12:34:56.123Z
131+ β’ 2024-01-01 12:34:56
132+ β’ 2024-01-01
133+ β’ 01/01/2024
134+ β’ 01-01-2024
135+ β’ UNIX timestamp: 1704067200 or 1704067200000
107136
108137## π¬ API
109138
@@ -128,8 +157,8 @@ json.isNull β Bool
128157## π§ͺ Testing
129158
130159Includes a full real-world test case covering:
131- β’ All primitive types
132- β’ Arrays and nested keys
133- β’ Date strings and timestamps
134- β’ Fuzzy and normalized keys
135- β’ Null and missing key handling
160+ β’ All primitive types
161+ β’ Arrays and nested keys
162+ β’ Date strings and timestamps
163+ β’ Fuzzy and normalized keys
164+ β’ Null and missing key handling
0 commit comments