JSON-DSL

Swift 5.1 Platform Current Version License

一个简单的特定领域语言 (DSL),用于在 Swift 中编写类型安全JSON

动机 🚀

我想在 Swift 中实现一个简单的 DSL 🙂

结果 🎁

结果是一个非常轻量级API

let json = JSON(
    .array(
        // 🚀 parses JSON encoded string and injects JSON elements
        .json("[\"Developer\",{\"name\":\"crelies\",\"language\":\"swift\",\"iOS versions\":[8.0,9.0,10.0,11.0,12.0,13.0],\"projects\":{\"name\":\"AdvancedList\",\"developers\":[{\"name\":\"crelies\"}]}},\"Age\",29,\"Swift\",5.1,{\"isActive\":true},null]"),

        "Developer",
        .object(.property("name", "crelies"),
                .property("language", "swift"),
                .property("iOS versions", .array(8.0, 9.0, 10.0, 11.0, 12.0, 13.0)),
                .property("projects", .object(.property("name", "AdvancedList"),
                                              .property("developers", .array(.object(.property("name", "crelies"))))))
        ),
        "Age",
        29,
        "Swift",
        5.1,
        .object(.property("isActive", true)),
        nil
    )
)

let renderedString = json.render()

输出

[
  [
    "Developer",
    {
      "name": "crelies",
      "language": "swift",
      "iOS versions": [
        8.0,
        9.0,
        10.0,
        11.0,
        12.0,
        13.0
      ],
      "projects": {
        "name": "AdvancedList",
        "developers": [
          {
            "name": "crelies"
          }
        ]
      }
    },
    "Age",
    29,
    "Swift",
    5.1,
    {
      "isActive": true
    },
    null
  ],
  "Developer",
  {
    "name": "crelies",
    "language": "swift",
    "iOS versions": [
      8.0,
      9.0,
      10.0,
      11.0,
      12.0,
      13.0
    ],
    "projects": {
      "name": "AdvancedList",
      "developers": [
        {
          "name": "crelies"
        }
      ]
    }
  },
  "Age",
  29,
  "Swift",
  5.1,
  {
    "isActive": true
  },
  null
]

⚠️注意:如果你使用 .json(),你最终可能会得到无效的 JSON。你需要知道一个 JSON 编码的字符串是否允许在特定的层级结构中使用(例如:属性不允许在数组中使用)!

高级示例 🔬

当涉及到 Strings 时,情况变得复杂 💣

你可以使用

提示:请记住,如果你使用未转义的 JSON 字符串,你可能会得到无效的 JSON (见下面的 ❌ 示例)。

示例

let json = JSON(
    .array(
        // ✅ parses JSON string and injects JSON elements
        .json("[\"Developer\",{\"name\":\"crelies\",\"language\":\"swift\",\"iOS versions\":[8.0,9.0,10.0,11.0,12.0,13.0],\"projects\":{\"name\":\"AdvancedList\",\"developers\":[{\"name\":\"crelies\"}]}},\"Age\",29,\"Swift\",5.1,{\"isActive\":true},null]"),

        // ########################################################################################
        // ✅ raw strings, surrounding double quotes will be escaped

        // - 1. Escaped characters
        #"[\"Developer\",{\"name\":\"crelies\",\"language\":\"swift\",\"iOS versions\":[8.0,9.0,10.0,11.0,12.0,13.0],\"projects\":{\"name\":\"AdvancedList\",\"developers\":[{\"name\":\"crelies\"}]}},\"Age\",29,\"Swift\",5.1,{\"isActive\":true},null]"#,

        // - 2. No escaped characters
        #"Without escaped characters"#,
        // ########################################################################################

        // ✅ plain string
        "Without escaped characters",

        // ########################################################################################
        /*
            Not working because surrounding double quotes are not escaped.
            (conflict with required JSON double quotes)
            ---> Will result in invalid JSON 💣
        */

        // ❌
        // "[\"Developer\",{\"name\":\"crelies\",\"language\":\"swift\",\"iOS versions\":[8.0,9.0,10.0,11.0,12.0,13.0],\"projects\":{\"name\":\"AdvancedList\",\"developers\":[{\"name\":\"crelies\"}]}},\"Age\",29,\"Swift\",5.1,{\"isActive\":true},null]"
        // ########################################################################################
    )
)

输出

[
  [
    "Developer",
    {
      "name": "crelies",
      "language": "swift",
      "iOS versions": [
        8.0,
        9.0,
        10.0,
        11.0,
        12.0,
        13.0
      ],
      "projects": {
        "name": "AdvancedList",
        "developers": [
          {
            "name": "crelies"
          }
        ]
      }
    },
    "Age",
    29,
    "Swift",
    5.1,
    {
      "isActive": true
    },
    null
  ],
  "[\"Developer\",{\"name\":\"crelies\",\"language\":\"swift\",\"iOS versions\":[8.0,9.0,10.0,11.0,12.0,13.0],\"projects\":{\"name\":\"AdvancedList\",\"developers\":[{\"name\":\"crelies\"}]}},\"Age\",29,\"Swift\",5.1,{\"isActive\":true},null]",
  "Without escaped characters",
  "Without escaped characters"
]