Coolie

Coolie(苦力) helps you to create models (& their constructors) from JSON file.

Coolie(苦力)

Coolie parse a JSON file to generate models (& their constructors).

Working with JSON in Swift

中文介绍:制作一个苦力

Requirements

Swift 3.0

Example

test.json:

{
  "name": "NIX",
  "detail": {
    "age": 18,
    "gender": null,
    "is_dog_lover": true,
    "skills": [
      "Swift on iOS",
      "C on Linux"
    ],
    "motto": "爱你所爱,恨你所恨。",
    "daily_fantasy_hours": [-0.1, 3.5, 4.2]
  },
  "projects": [
    {
      "name": "Coolie",
      "url": "https://github.com/nixzhu/Coolie"
    }
  ]
}

Build coolie & run:

$ swift build
$ ./.build/debug/coolie -i test.json --model-name User --argument-label json

It will generate:

struct User {
    struct Detail {
        let age: Int
        let dailyFantasyHours: [Double]
        let gender: UnknownType?
        let isDogLover: Bool
        let motto: String
        let skills: [String]
        init?(json info: [String: Any]) {
            guard let age = info["age"] as? Int else { return nil }
            guard let dailyFantasyHours = info["daily_fantasy_hours"] as? [Double] else { return nil }
            let gender = info["gender"] as? UnknownType
            guard let isDogLover = info["is_dog_lover"] as? Bool else { return nil }
            guard let motto = info["motto"] as? String else { return nil }
            guard let skills = info["skills"] as? [String] else { return nil }
            self.age = age
            self.dailyFantasyHours = dailyFantasyHours
            self.gender = gender
            self.isDogLover = isDogLover
            self.motto = motto
            self.skills = skills
        }
    }
    let detail: Detail
    let name: String
    struct Project {
        let name: String
        let url: String
        init?(json info: [String: Any]) {
            guard let name = info["name"] as? String else { return nil }
            guard let url = info["url"] as? String else { return nil }
            self.name = name
            self.url = url
        }
    }
    let projects: [Project]
    init?(json info: [String: Any]) {
        guard let detailJSONDictionary = info["detail"] as? [String: Any] else { return nil }
        guard let detail = Detail(json: detailJSONDictionary) else { return nil }
        guard let name = info["name"] as? String else { return nil }
        guard let projectsJSONArray = info["projects"] as? [[String: Any]] else { return nil }
        let projects = projectsJSONArray.map({ Project(json: $0) }).flatMap({ $0 })
        self.detail = detail
        self.name = name
        self.projects = projects
    }
}

Pretty cool, ah?

Now you can modify the models (the name of properties or their type) if you need.

You can specify constructor name, argument label, or json dictionary name, like following command:

$ ./.build/debug/coolie -i test.json --model-name User --constructor-name create --argument-label with --json-dictionary-name JSONDictionary

It will generate:

struct User {
    struct Detail {
        let age: Int
        let dailyFantasyHours: [Double]
        let gender: UnknownType?
        let isDogLover: Bool
        let motto: String
        let skills: [String]
        static func create(with info: JSONDictionary) -> Detail? {
            guard let age = info["age"] as? Int else { return nil }
            guard let dailyFantasyHours = info["daily_fantasy_hours"] as? [Double] else { return nil }
            let gender = info["gender"] as? UnknownType
            guard let isDogLover = info["is_dog_lover"] as? Bool else { return nil }
            guard let motto = info["motto"] as? String else { return nil }
            guard let skills = info["skills"] as? [String] else { return nil }
            return Detail(age: age, dailyFantasyHours: dailyFantasyHours, gender: gender, isDogLover: isDogLover, motto: motto, skills: skills)
        }
    }
    let detail: Detail
    let name: String
    struct Project {
        let name: String
        let url: String
        static func create(with info: JSONDictionary) -> Project? {
            guard let name = info["name"] as? String else { return nil }
            guard let url = info["url"] as? String else { return nil }
            return Project(name: name, url: url)
        }
    }
    let projects: [Project]
    static func create(with info: JSONDictionary) -> User? {
        guard let detailJSONDictionary = info["detail"] as? JSONDictionary else { return nil }
        guard let detail = Detail.create(with: detailJSONDictionary) else { return nil }
        guard let name = info["name"] as? String else { return nil }
        guard let projectsJSONArray = info["projects"] as? [JSONDictionary] else { return nil }
        let projects = projectsJSONArray.map({ Project.create(with: $0) }).flatMap({ $0 })
        return User(detail: detail, name: name, projects: projects)
    }
}

You may need typealias JSONDictionary = [String: Any] at first.

If you need class model, use the following command:

$ ./.build/debug/coolie -i test.json --model-name User --model-type class

Also --argument-label and --json-dictionary-name options are available for class.

If you need more information for debug, append a --debug option in all the commands.

Contact

NIX @nixzhu

License

Coolie is available under the MIT License. See the LICENSE file for more info.

Related Repositories

dev-blog

dev-blog

翻译、开发心得或学习笔记 ...

treasure

treasure

互联网时代前端"手工艺人"的百宝箱 ...

coolie.js

coolie.js

一个纯净、易用的模块加载器。 ...

alien

alien

一个为现代浏览器而生的前端解决方案。 ...

coolie-cli

coolie-cli

前端构建工具 ...


Top Contributors

nixzhu neilco