Skip to content

nixzhu/Banana

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Banana

A lightweight, high‑performance JSON decoding library powered by yyjson.

Example

Given the following JSON:

{
    "profile": {
        "nickname": "NIX",
        "username": "@[email protected]",
        "avatar": {
            "url": "https://example.com/nixzhu.png",
            "width": 200,
            "height": 200
        }
    },
    "toots": [
        {
            "id": 1,
            "content": "Hello World!",
            "created_at": "2024-10-05T09:41:00.789Z"
        },
        {
            "id": 2,
            "content": "How do you do?",
            "created_at": "2025-04-29T22:23:24.567Z"
        }
    ]
}

You can define your models by conforming to the BananaModel protocol:

import Foundation
import Banana

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

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

extension Mastodon {
    struct Profile: BananaModel {
        let nickname: String
        let username: String
        let avatar: Avatar

        init(json: BananaJSON) {
            nickname = json.nickname.string()
            username = json.username.string()
            avatar = .init(json: json.avatar)
        }
    }
}

extension Mastodon.Profile {
    struct Avatar: BananaModel {
        let url: URL
        let width: Double
        let height: Double

        init(json: BananaJSON) {
            url = json["url"].url()
            width = json.width.double()
            height = json.height.double()
        }
    }
}

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

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

To decode a Mastodon instance from the JSON string:

let mastodon = Mastodon.decode(from: jsonString)

Or, if you already have the JSON data:

let mastodon = Mastodon.decode(from: jsonData)

To decode a specific JSON branch, for example profile.avatar, specify it's path:

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

To decode an array (e.g. toots):

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

Or decode only the first toot:

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

Installation

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swiftcompiler.

Once your Swift package is set up, add Banana as a dependency to the dependencies value in your Package.swift file or to the package list in Xcode.

dependencies: [
    .package(url: "https://github.com/nixzhu/Banana.git", from: "0.4.0"),
]

Typically, you will want to depend on the Banana target:

.product(name: "Banana", package: "Banana")

About

A lightweight, high‑performance JSON decoding library powered by yyjson.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages