CowCodable provides deterministic, production-safe JSON resilience for Swift models using a single wrapper:
@CowResilient var value: Int = 0Real backend payloads frequently drift:
- Type mismatches (
"42"instead of42) - Partially corrupted arrays/dictionaries
- Missing keys vs explicit
null
CowCodable handles these cases explicitly while avoiding silent corruption.
- Deterministic rescue
- No silent corruption
- No unsafe coercion
- Strong type safety
- Configurable null strategy
CowResilient<Value> supports deterministic rescue for:
String,Int,Double,Float,Bool,Character- Arrays of supported primitive types
- Nested arrays of supported primitive types
[String: SupportedPrimitive]- Nested dictionaries of supported primitive values
| From JSON | To Swift | Strict | Permissive |
|---|---|---|---|
Int |
String |
Yes | Yes |
Double |
String |
Yes | Yes |
Bool |
String |
Yes | Yes |
Numeric String |
Int |
Yes ("42") |
Yes ("42", "1e3" when integral) |
Double |
Int |
Yes (integral only) | Yes (integral only) |
Numeric String |
Double |
Yes | Yes |
Numeric String |
Float |
Yes | Yes (NaN/Infinity allowed) |
Bool-like String |
Bool |
Yes | Yes |
Single-character String |
Character |
Yes | Yes |
| Integer Unicode scalar | Character |
No | Yes |
| Scalar | [T] |
No | Yes (single wrapped element) |
Ambiguous coercions always fail (12.3 -> Int, overflowed numeric conversions).
CowConfiguration.defaultRescueStrategy = StrictRescueStrategy.self
CowConfiguration.defaultRescueStrategy = PermissiveRescueStrategy.selfStrictRescueStrategy: minimal deterministic coercion.PermissiveRescueStrategy: broader deterministic coercion for known backend drift.
CowConfiguration.defaultNullStrategy = .fail
CowConfiguration.defaultNullStrategy = .useDefault
CowConfiguration.defaultNullStrategy = .skipCowResilient explicitly distinguishes:
- Missing key
- Explicit
null - Invalid type
CowCodable emits structured logs through CowLogger:
- rescued values
- skipped entries
- failures
Logs include coding paths and raw values for diagnostics and UI presentation.
CowCodable/
├── Package.swift
├── README.md
├── Sources/CowCodable/
│ ├── Core/
│ ├── Bridge/
│ ├── Defaults/
│ ├── Logging/
│ └── Extensions/
├── Tests/CowCodableTests/
├── Examples/
├── docs/screenshots/
└── DemoApp/CowCodableDemoApp/
├── CowCodableDemoApp.xcodeproj
└── CowCodableDemoApp/
- Swift 5.9+
- iOS 16.0+
- macOS 13.0+
- Xcode 15+
CowCodable uses modern Swift concurrency and type-safe rescue strategies.
- Open your project in Xcode.
- Go to File → Add Package Dependencies…
- Enter the repository URL: https://github.com/ANSCoder/CowCodable.git
- Select the latest version.
- Add the CowCodable library to your target.
Add CowCodable to your dependencies:
dependencies: [
.package(url: "https://github.com/ANSCoder/CowCodable.git", from: "1.0.0")
]The repository includes a separate iOS SwiftUI demo app target:
- Project:
DemoApp/CowCodableDemoApp/CowCodableDemoApp.xcodeproj - Minimum iOS:
16.0 - Interface: SwiftUI (no storyboard)
- Open
DemoApp/CowCodableDemoApp/CowCodableDemoApp.xcodeprojin Xcode. - Select the
CowCodableDemoAppscheme. - Choose an iOS 16+ simulator device.
- Build and run.
The app imports CowCodable as a local Swift package dependency from this repository root and does not duplicate SDK sources.
Primitive Corruption: primitive type drift and deterministic rescue.Array Corruption: mixed arrays with rescued and skipped elements.Dictionary Corruption: value rescue and deterministic invalid entry dropping.Nested Complex: nested resilience across multiple levels.Null Edge Case: null/missing behavior under different null strategies.Overflow Case: deterministic overflow and non-finite numeric handling.Strict vs Permissive Case: side-by-side behavior change with identical input.
Strictapplies minimal deterministic coercion.Permissiveallows additional deterministic conversions (for example scientific notation-to-int when integral, scalar-to-array wrapping, Unicode scalar character conversion).
Switching the segmented control changes only the configured rescue policy; input JSON stays unchanged so behavior differences are observable.
## Example Modelstruct Profile: Codable {
@CowResilient var id: String = ""
@CowResilient var score: Double = 0
@CowResilient var flags: [Bool] = []
}- O(1) direct primitive rescue
- O(n) array/dictionary rescue
- No reflection or runtime type hacks
CowResilientis value-based andSendablewhenValueisSendable.CowConfigurationandCowLoggerare lock-protected.- Decode on background queues and update UI on main thread.
- No rescue for arbitrary
Codableobject graphs via reflection - No ambiguous coercion
- No hidden mutation of invalid backend data
- No magic auto-fixes outside documented conversion rules
The repository uses deterministic validation for both SDK and demo app:
swift buildswift testxcodebuild -project DemoApp/CowCodableDemoApp/CowCodableDemoApp.xcodeproj -scheme CowCodableDemoApp -destination 'generic/platform=iOS Simulator' CODE_SIGNING_ALLOWED=NO build
These checks run in CI at .github/workflows/ci.yml.
This project enforces consistent formatting via:
.editorconfig(editor-level policy).swiftformat(SwiftFormat configuration)
Formatting is validated in CI.
CowCodable is released under the MIT License.
See the LICENSE file for details.



