LazyCodableKit provides property wrappers that gracefully decode inconsistent server values into valid Swift types.
It supports automatic fallback handling, optional decoding and configurable logging for safer and more flexible model parsing.
- Decode
Int,Double,String, andBoolfrom mixed or malformed formats - Use fallback values when decoding fails
- Optional variants decode to
nilon failure - Lightweight and dependency-free
- Fully compatible with Swift Concurrency (async/await)
By default, all logs are disabled. Enable detailed decoding logs like this:
import LazyCodableKit
// Turn on logging for all wrappers
LazyCodableLogger.isEnabled = true
// (Optional) Also log successful conversions (โ
)
// LazyCodableLogger.logOnSuccess = true
// (Optional) Customize log output destination
LazyCodableLogger.handler = { message in
// e.g. os_log, Crashlytics, write to file
print(message)
}When enabled, youโll see entries like:
[LazyCodableKit] ๐user.age: ๐ String("25") โ Int(25)
[LazyCodableKit] ๐user.score: โ ๏ธ Unknown value โ fallback to -1
[LazyCodableKit] ๐user.nickname: ๐ซ JSON null โ nil
- ๐ converted: type coercion events
โ ๏ธ fallback: mismatches falling back to default- ๐ซ null: JSON
nullโnil - โ
success: (only if
logOnSuccess = true)
Add to your Package.swift:
.package(url: "https://github.com/kvngwxxk/LazyCodableKit.git", from: "1.0.0")Then import:
import LazyCodableKitIn your Podfile:
pod 'LazyCodableKit', '~> 1.0.0'Then:
pod installstruct User: Codable {
@PromisedInt var age: Int
@PromisedBool var isActive: Bool
@PromisedString var nickname: String
@PromisedDouble var rating: Double
@PromisedDate var createdAt: Date
}struct User: Codable {
@PromisedOptionalInt var age: Int?
@PromisedOptionalBool var isActive: Bool?
@PromisedOptionalString var nickname: String?
@PromisedOptionalDouble var rating: Double?
@PromisedOptionalDate var createdAt: Date?
}| Wrapper | Accepts | Fallback (default) | Notes |
|---|---|---|---|
@PromisedInt |
Int, "123", 123.4, true |
-1 |
|
@PromisedBool |
true, "yes", 1, "false" |
false |
|
@PromisedString |
"str", 123, true |
"" |
|
@PromisedDouble |
123.45, "123", true |
-1.0 |
|
@PromisedDate |
ISO8601, "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" |
Date.distantPast |
Available since 1.1.0 |
@PromisedOptional* |
Same as above, but returns nil on failure |
nil |
Here's a full example that uses all Promised property wrappers with nested types and arrays:
struct Badge: Codable {
@PromisedString var title: String
@PromisedOptionalInt var level: Int?
}
struct Profile: Codable {
@PromisedString var bio: String
@PromisedOptionalBool var isVerified: Bool?
@PromisedOptionalDate var birthday: Date?
}
struct User: Codable {
@PromisedInt var id: Int
@PromisedOptionalString var nickname: String?
@PromisedBool var isActive: Bool
@PromisedDouble var rating: Double
@PromisedOptionalDouble var optionalScore: Double?
@PromisedDate var createdAt: Date
var profile: Profile
var badges: [Badge]
}
let json = """
{
"id": "1001",
"nickname": 123,
"isActive": "yes",
"rating": "4.7",
"optionalScore": null,
"createdAt": "2023-11-20 12:34:56",
"profile": {
"bio": true,
"isVerified": "no",
"birthday": "2000-01-01"
},
"badges": [
{ "title": 456, "level": "3" },
{ "title": null, "level": {} }
]
}
""".data(using: .utf8)!
LazyCodableLogger.isEnabled = true
let user = try JSONDecoder().decode(User.self, from: json)[LazyCodableKit] ๐id: ๐ String("1001") โ Int(1001)
[LazyCodableKit] ๐nickname: ๐ Int(123) โ String("123")
[LazyCodableKit] ๐isActive: ๐ String("yes") โ Bool(true)
[LazyCodableKit] ๐rating: ๐ String("4.7") โ Double(4.7)
[LazyCodableKit] ๐optionalScore: ๐ซ JSON null โ nil
[LazyCodableKit] ๐createdAt: ๐ String("2023-11-20 12:34:56") โ Date(2023-11-20 12:34:56 +0000)
[LazyCodableKit] ๐profile.bio: ๐ Bool(true) โ String("true")
[LazyCodableKit] ๐profile.isVerified: ๐ String("no") โ Bool(false)
[LazyCodableKit] ๐profile.birthday: ๐ String("2000-01-01") โ Date(2000-01-01 00:00:00 +0000)
[LazyCodableKit] ๐badges.Index 0.title: ๐ Int(456) โ String("456")
[LazyCodableKit] ๐badges.Index 0.level: ๐ String("3") โ Int(3)
[LazyCodableKit] ๐badges.Index 1.title: โ ๏ธ Unknown value โ fallback to ""
[LazyCodableKit] ๐badges.Index 1.level: ๐ซ Unknown value โ nil
- iOS 13+
- macOS 11+
LazyCodableKit is released under the MIT License.
Contributions, issues, and feature requests are welcome!
Feel free to file an issue or submit a pull request.