ZCJSON is a powerful JSON parsing library for Swift that extends Codable with additional features like default values, type conversion, and Any type handling.
- 🎯 Automatic default values for missing fields
- 🔄 String to number conversion
- 📦 Any type handling (dictionaries and arrays)
- 🚫 Field ignoring with annotations
- 👥 Inheritance support
- 🎲 Enum handling with default cases
- 🏗️ Macro support for code generation
ZCJSON is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'ZCJSON'ZCJSON supports installation via Swift Package Manager. In Xcode:
- Select File > Add Packages...
- Enter the package URL:
https://github.com/ZClee128/ZCJSON.git - Choose version rules (Up to Next Major recommended)
- Click Add Package
Or add the dependency directly in your Package.swift:
dependencies: [
.package(url: "https://github.com/ZClee128/ZCJSON.git", from: "1.0.0")
]// Dictionary to model
let model = data.asDecodable(Model.self)
// Model to JSON string
model.toJSONString()
// Parse with designated path
let jsonString = """
{
"code": 200,
"msg": "success",
"data": {
"cat": {
"id": 12345,
"name": "Kitty"
}
}
}
"""
struct Cat: Codable {
var id: Int64
var name: String
}
if let cat = jsonString.asDecodable(Cat.self, designatedPath: "data.cat") {
print(cat.name) // Prints "Kitty"
}ZCJSON provides default values for missing fields in your JSON:
struct User: Codable {
let name: String
let age: Int // Will be 0 if missing
@Default<Bool.False>
var isActive: Bool // Will be false if missing
@Default<Bool.True>
var isVerified: Bool // Will be true if missing
}Automatically converts string numbers to numeric types:
struct Product: Codable {
let id: Int // "123" -> 123
let price: CGFloat // "99.99" -> 99.99
}Handle dynamic JSON structures with Any type:
@zcCodable
struct DynamicModel: Codable {
var data: [String: Any]
var items: [Any]
}Ignore specific fields during parsing:
struct User: Codable {
@zcAnnotation(key: ["password"], ignore: true)
var password: String = "default"
}Handle enums with default cases:
enum Status: String, Codable, CaseDefaultsFirst {
case active
case inactive
case pending
}
struct TestModel: Codable {
var status: Status
}
let jsonString = """
{
"status": "invalid" // Will default to first case
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.status, .active) // Defaults to first case
}Handle enums with integer values:
enum TestType: Int, Codable, CaseDefaultsFirst {
case none = -1
case one = 1
}
struct TestModel: Codable {
let name: String
let age: Int
let type: TestType
}
let jsonString = """
{
"name": "aa",
"age": "10",
"type": 1
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.name, "aa")
XCTAssertEqual(decoded.age, 10)
XCTAssertEqual(decoded.type, .one) // Parses integer value to enum case
}Support for class inheritance in JSON parsing:
class BaseModel: Codable {
var name: String
}
@zcInherit
class UserModel: BaseModel {
var age: Int
}@zcCodable
struct ComplexModel: Codable {
// Default values
@Default<Bool.True>
var isEnabled: Bool
// String to number conversion
let count: Int
// Any type handling
var metadata: [String: Any]
var items: [Any]
// Enum with default case
var status: Status
// Ignored field
@zcAnnotation(key: ["internal"], ignore: true)
var internalData: String = "default"
}ZCJSON includes comprehensive unit tests covering:
- ✅ Default value handling
- ✅ Type conversion
- ✅ Any type parsing
- ✅ Field ignoring
- ✅ Inheritance
- ✅ Enum handling
Run tests using ⌘U or Product -> Test to verify functionality.
ZClee128, 876231865@qq.com
ZCJSON is available under the MIT license. See the LICENSE file for more info.
If you encounter any parsing issues or have questions, feel free to contact me or join our QQ group: 982321096
ZCJSON comes with extensive unit tests that cover common JSON parsing scenarios, including but not limited to:
- ✅ Default value fallback when fields are missing (
Int,Float,Bool,String, etc.) - ✅ Type conversion from strings to numbers: e.g.
"10"→Int,CGFloat,Double - ✅ Supports hybrid model decoding of
[String: Any]and[Any] - ✅ Graceful decoding of dynamic
Anyvalues - ✅ Declarative default values via the
@Defaultproperty wrapper - ✅ Extended default support for numeric types:
UInt8/16/32/64,Int8/16/32/64 - ✅ Enum fallback decoding with
CaseDefaultsFirst - ✅ Field ignoring and key remapping via
@zcAnnotation - ✅ Compatibility between macro-generated models and manually implemented models
💡 Example: See
Tests.swiftfor full use of.asDecodable()and validation of@zcCodableerror-tolerant decoding behavior.
Run tests via ⌘U or Product -> Test to verify parsing stability and behavior.
ZCJSON automatically handles missing fields with appropriate default values:
// Test missing field with default value
struct TestModel: Codable {
let name: String
let age: Int // Will be 0 if missing
}
let jsonString = """
{
"name": "Alice"
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.name, "Alice")
XCTAssertEqual(decoded.age, 0) // Default value for missing field
}You can specify custom default values using @Default:
struct TestModel: Codable {
let name: String
let age: CGFloat
@Default<Bool.False>
var isStudent: Bool
@Default<Bool.True>
var isTeacher: Bool
}
let jsonString = """
{
"name": "Alice"
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.name, "Alice")
XCTAssertEqual(decoded.age, 0.0)
XCTAssertEqual(decoded.isStudent, false) // Custom default
XCTAssertEqual(decoded.isTeacher, true) // Custom default
}Automatic conversion from string to numeric types:
struct TestModel: Codable {
let age: Int
let age1: CGFloat
}
let jsonString = """
{
"age": "10",
"age1": "10.0"
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.age, 10) // String "10" converted to Int
XCTAssertEqual(decoded.age1, 10.0) // String "10.0" converted to CGFloat
}Handle dynamic JSON structures with Any type:
@zcCodable
struct TestAnyModel: Codable {
var age: Any
@zcAnnotation(key: ["age1"], ignore: true)
var age1: Float = 40
var data: [String: Any]
var arr: [Any]
}
let jsonString = """
{
"age": "10",
"age1": "10.0",
"data": {
"a": 1,
"b": "2"
},
"arr": ["1", "2"]
}
"""
if let decoded = jsonData.asDecodable(TestAnyModel.self) {
XCTAssertEqual(decoded.age as! String, "10")
XCTAssertEqual(decoded.age1, 40.0) // Ignored field with default value
XCTAssertEqual(decoded.data["a"] as? Int, 1)
XCTAssertEqual(decoded.data["b"] as? String, "2")
XCTAssertEqual(decoded.arr as? [String], ["1", "2"])
}Ignore specific fields during parsing:
@zcCodable
struct TestAnyModel: Codable {
@zcAnnotation(key: ["age1"], ignore: true)
var age1: Float = 40
var data: [String: Any]
}
let jsonString = """
{
"age1": "10.0",
"data": {
"a": 1,
"b": "2"
}
}
"""
if let decoded = jsonData.asDecodable(TestAnyModel.self) {
XCTAssertEqual(decoded.age1, 40.0) // Ignored field keeps default value
XCTAssertEqual(decoded.data["a"] as? Int, 1)
}Support for class inheritance in JSON parsing:
class BaseModel: Codable {
var name: String
}
@zcInherit
class OneModel: BaseModel {
var age: Int
}
let jsonString = """
{
"name": "aa",
"age": "10"
}
"""
if let decoded = jsonData.asDecodable(OneModel.self) {
XCTAssertEqual(decoded.name, "aa")
XCTAssertEqual(decoded.age, 10)
}Handle enums with default cases:
enum Status: String, Codable, CaseDefaultsFirst {
case active
case inactive
case pending
}
struct TestModel: Codable {
var status: Status
}
let jsonString = """
{
"status": "invalid" // Will default to first case
}
"""
if let decoded = jsonData.asDecodable(TestModel.self) {
XCTAssertEqual(decoded.status, .active) // Defaults to first case
}![]() WECO |
![]() WEGAME |
![]() 玉玄道 |


