Latest 1.1.2
Homepage https://github.com/zoul/generic-json-swift
License MIT
Platforms ios 10.0, osx 10.14

Generic JSON

Build Status

Generic JSON makes it easy to deal with freeform JSON strings without creating a separate, well-typed structure.

Codable and freeform JSON

Swift 4 introduced a new JSON encoding and decoding machinery represented by the Codable protocol. The feature is very nice and very type-safe, meaning it’s no longer possible to just willy-nilly decode a JSON string pulling random untyped data from it. Which is good™ most of the time – but what should you do when you do want to just willy-nilly encode or decode a JSON string without introducing a separate, well-typed structure for it? For example:

// error: heterogeneous collection literal could only be inferred to '[String : Any]';
// add explicit type annotation if this is intentional
let json = [
    "foo": "foo",
    "bar": 1,
]

// Okay then:
let json: [String:Any] = [
    "foo": "foo",
    "bar": 1,
]

// But: fatal error: Dictionary<String, Any> does not conform to Encodable because Any does not conform to Encodable.
let encoded = try JSONEncoder().encode(json)

So this doesn’t work very well. Also, the json value can’t be checked for equality with another, although arbitrary JSON values should support equality. Enter JSON.

Usage

Create a JSON structure

let json: JSON = [
    "foo": "foo",
    "bar": 1,
]

// "{"bar":1,"foo":"foo"}"
let str = try String(data: try JSONEncoder().encode(json), encoding: .utf8)!
let hopefullyTrue = (json == json) // true!

Convert Encodable objects into a generic JSON structure

struct Player: Codable {
    let name: String
    let swings: Bool
}

let val = try JSON(encodable: Player(name: "Miles", swings: true))
val == [
    "name": "Miles",
    "swings": true,
] // true

Query Values

Consider the following JSON structure:

let json: JSON = [
    "num": 1,
    "str": "baz",
    "bool": true,
    "obj": [
        "foo": "jar",
        "bar": 1,
    ]
]

Querying values can be done using optional property accessors, subscripting or dynamic member subscripting:

// Property accessors
if let str = json.objectValue?["str"]?.stringValue { … }
if let foo = json.objectValue?["obj"]?.objectValue?["foo"]?.stringValue { … }

// Subscripting
if let str = json["str"]?.stringValue { … }
if let foo = json["obj"]?["foo"]?.stringValue { … }

// Dynamic member subscripting
if let str = json.str?.stringValue { … }
if let foo = json.obj?.foo?.stringValue { … }

You may even drill through nested structures using a dot-separated key path:

let val = json[keyPath: "obj.foo"] // "jar"

Latest podspec

{
    "name": "GenericJSON",
    "platforms": {
        "ios": "10.0",
        "osx": "10.14"
    },
    "version": "1.1.2",
    "license": {
        "type": "MIT"
    },
    "homepage": "https://github.com/zoul/generic-json-swift",
    "authors": "Tomu00e1u0161 Znamenu00e1u010dek",
    "summary": "A simple Swift library for working with generic JSON structures.",
    "source": {
        "git": "https://github.com/zoul/generic-json-swift.git",
        "tag": "release/1.1.2"
    },
    "source_files": "GenericJSON/*.swift",
    "swift_version": "4.1"
}

Pin It on Pinterest

Share This