Ananda

0.8.0

JSON model decoding based on yyjson.
nixzhu/Ananda

What's New

Version 0.8.0

2024-03-16T06:22:39Z
  • Support Swift Syntax 5.10
  • Enable Strict Concurrency

Ananda

JSON model decoding based on yyjson.

Example

We have JSON as follow:

{
  "profile": {
    "nickname": "NIX",
    "username": "@nixzhu@mastodon.social",
    "avatar_url": "https://files.mastodon.social/accounts/avatars/109/329/064/034/222/219/original/371901c6daa01207.png"
  },
  "toots": [
    {
      "id": 1,
      "content": "Hello World!",
      "created_at": "1674127714"
    },
    {
      "id": 2,
      "content": "How do you do?",
      "created_at": "1674127720"
    }
  ]
}

And we create models conforms to AnandaModel protocol as follow:

import Foundation
import Ananda

struct Mastodon: AnandaModel {
    let profile: Profile
    let toots: [Toot]

    init(json: AnandaJSON) {
        profile = .init(json: json.profile)
        toots = json.toots.array().map { .init(json: $0) }
    }
}

extension Mastodon {
    struct Profile: AnandaModel {
        let nickname: String
        let username: String
        let avatarURL: URL

        init(json: AnandaJSON) {
            username = json.username.string()
            nickname = json.nickname.string()
            avatarURL = json.avatar_url.url()
        }
    }
}

extension Mastodon {
    struct Toot: AnandaModel {
        let id: Int
        let content: String
        let createdAt: Date

        init(json: AnandaJSON) {
            id = json.id.int()
            content = json.content.string()
            createdAt = json.created_at.date()
        }
    }
}

Then, we can decode a Mastodon as follow:

let mastodon = Mastodon.decode(from: jsonString)

Or

let mastodon = Mastodon.decode(from: jsonData)

If you only want to decode a part of the JSON, like profile, use the path to specify it as follow:

let profile = Mastodon.Profile.decode(from: jsonData, path: ["profile"])

How about just decode toots? It's an array, do it as follow:

let toots = [Mastodon.Toot].decode(from: jsonData, path: ["toots"])

Swift Macro

With Swift 5.9, you can use macro to eliminate the initialization methods as follow:

import Foundation
import Ananda

@AnandaInit
struct Mastodon: AnandaModel {
    let profile: Profile
    let toots: [Toot]
}

extension Mastodon {
    @AnandaInit
    struct Profile: AnandaModel {
        let nickname: String
        let username: String
        @AnandaKey("avatar_url")
        let avatarURL: URL
    }
}

extension Mastodon {
    @AnandaInit
    struct Toot: AnandaModel {
        let id: Int
        let content: String
        @AnandaKey("created_at")
        let createdAt: Date
    }
}

Simple and clean, right?

Benchmark

See AnandaBenchmark.

Tool

You may use Ducky Model Editor to generate AnandaModel from JSON to save your time.

Ducky Model Editor

Ducky Model Editor

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

Last updated: Fri Apr 19 2024 01:21:15 GMT-0900 (Hawaii-Aleutian Daylight Time)