Skip to content

kvngwxxk/LazyCodableKit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

41 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

LazyCodableKit โ€“ Safe & Flexible Decoding for Swift

๐Ÿ“˜ View this page in Korean

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.

๐Ÿš€ Features

  • Decode Int, Double, String, and Bool from mixed or malformed formats
  • Use fallback values when decoding fails
  • Optional variants decode to nil on failure
  • Lightweight and dependency-free
  • Fully compatible with Swift Concurrency (async/await)

๐Ÿ“ข Logging

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)

๐Ÿ“ฆ Installation

Swift Package Manager

Add to your Package.swift:

.package(url: "https://github.com/kvngwxxk/LazyCodableKit.git", from: "1.0.0")

Then import:

import LazyCodableKit

CocoaPods

In your Podfile:

pod 'LazyCodableKit', '~> 1.0.0'

Then:

pod install

๐Ÿ› ๏ธ Usage

Promised (non-optional) decoding

struct User: Codable {
    @PromisedInt var age: Int
    @PromisedBool var isActive: Bool
    @PromisedString var nickname: String
    @PromisedDouble var rating: Double
    @PromisedDate var createdAt: Date    
}

Optional decoding (fails silently)

struct User: Codable {
    @PromisedOptionalInt var age: Int?
    @PromisedOptionalBool var isActive: Bool?
    @PromisedOptionalString var nickname: String?
    @PromisedOptionalDouble var rating: Double?
    @PromisedOptionalDate var createdAt: Date?
}

๐Ÿ“‹ Supported Formats

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

๐Ÿ” Quick Example

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)

Console

[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

โœ… Minimum Requirements

  • iOS 13+
  • macOS 11+

๐Ÿ“„ License

LazyCodableKit is released under the MIT License.

๐Ÿ”— Contribution

Contributions, issues, and feature requests are welcome!
Feel free to file an issue or submit a pull request.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors