Skip to content
/ Nson Public

Nson provides a more convenient way to handle Decodable and Encodable through Property Wrappers.

License

Notifications You must be signed in to change notification settings

devhplusn/Nson

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nson

Swift Platforms GitHub license

Nson provides a more convenient way to handle Decodable and Encodable through Property Wrappers.

Requirements

  • Swift 5.0
  • iOS 11.0+
  • macOS 10.13+
  • tvOS 11.0+
  • watchOS 4.0+

Installation

Swift Package Manager

You can use The Swift Package Manager to install Nson by adding the proper description to your Package.swift file:

import PackageDescription

let package = Package(
    name: "YOUR_PROJECT_NAME",
    targets: [],
    dependencies: [
        .package(url: "https://github.com/devhplusn/Nson.git", from: "1.0.0")
    ]
)

Cocoapods

Nson is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Nson', :tag => '1.0.0', :git => 'https://github.com/devhplusn/Nson'

Usage

Support alter Key

@Key allows you to process JSON decoding or encoding without CodingKeys and using custom keys. @Key uses the <- operator or KeyPaths to define how it maps to and from JSON. The nested key accepts additional keys as arguments. The object needs to implement the NSON protocol.

Example JSON:

{
  "name": "tanaka",
  "info": {
    "age": 20,
    "gender": "M",
    "email_address": "[email protected]"
  }
}

vanilla Codable:

struct Model {

    var name: String
    var age: Int
    var gender: String
    var email: String

    enum CodingKeys: String, CodingKey {
        case name
        case info
    }

    enum InfoKeys: String, CodingKey {
        case age
        case gender
        case email = "email_address"
    }
}

extension Model: Decodable {

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        let nestedContainer = try container.nestedContainer(keyedBy: InfoKeys.self, forKey: .info)
        age = try nestedContainer.decode(Int.self, forKey: .age)
        gender = try nestedContainer.decode(String.self, forKey: .gender)
        email = try nestedContainer.decode(String.self, forKey: .email)
    }
}

extension Model: Encodable {

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
        var nestedContainer = container.nestedContainer(keyedBy: InfoKeys.self, forKey: .info)
        try nestedContainer.encode(age, forKey: .age)
        try nestedContainer.encode(gender, forKey: .gender)
        try nestedContainer.encode(email, forKey: .email)
    }
}

Nson:

struct Model: Codable, NSON {

    var name: String
    @Key("age" <- ["info", "age"])
    var age: Int
    @Key(to: \.gender, "info", "gender")
    var gender: String
    @Key("email" <- ["info", "email_address"])
    var email: String
}

// Decode
let model = try NSONDecoder().decode(Model.self, from: jsonData)

// Encode
let data = try NSONEncoder().encode(model)

Support flat

When you need to decode flat JSON values into nested structures or encode nested structures into flat JSON, you can handle it through the use of the @Flat property wrapper.

Example JSON:

{
  "name": "tanaka",
  "info_age": 20,
  "info_gender": "M"
}

Usage:

struct Model: Codable {

    var name: String
    @Flat
    var info: ModelInfo
}


struct ModelInfo: Codable, NSON {

    @Key("age" <- "info_age")
    var age: Int
    @Key(to: \.gender, "info_gender")
    var gender: String
}

Support transformer

To add custom transformations, please implement DecodeTransformable, EncodeTransformable, or CodeTransformable for bidirectional transformations.

Example JSON:

{
    "count": "10"
    "date": "2023-11-01"
}

Usage:

struct Object: Decodable {

    @Transform<ToInt>
    var count: Int

    @Transform<ToDate>
    var date: Date?
}

enum ToInt: CodeTransformable {

    typealias Value = Int

    static func transform(decoded: String) throws -> Value {
        Int(decoded) ?? 0
    }

    static func transform(value: Int) throws -> String {
        String(value)
    }
}

enum ToDate: DecodeTransformable {

    public typealias Value = Date?

    public static func transform(decoded: String) throws -> Value {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter.date(from: decoded)
    }
}

PropertyWrapper Combine

Can combine @Key and @Transform to handle JSON keys and transform decoded values when needed.

Example JSON:

{
    "count": "10"
}

Usage:

struct Object: Decodable {

    @Key("m_count" <- "count")
    @Transform<ToInt>
    var m_count: Int
}

enum ToInt: DecodeTransformable {

    typealias Value = Int

    static func transform(decoded: String) throws -> Value {
        Int(decoded) ?? 0
    }
}

License

These works are available under the MIT license. See the LICENSE file for more info.

About

Nson provides a more convenient way to handle Decodable and Encodable through Property Wrappers.

Resources

License

Stars

Watchers

Forks

Packages

No packages published