JSON
@dynamicMemberLookup
public enum JSON : Hashable, CustomStringConvertible
A representation of ambigious JSON.
Heterogeneous Arrays.
Take for exmaple the JSON below:
{
"users": [
{
"age": 18,
"name": {
"first": "Caleb",
"last": "Kleveter"
}
}
],
"metadata": [42, 3.14, true, "fizz buzz"]
}
The users
data is pretty normal, but the metadata
array can’t be represented by standard arrays.
The metadata
array, when decoded to a JSON
instance, will result in this case:
JSON.array([.number(.int(42)), .number(.double(3.14)), .bool(true), .string("fizz buzz")])
Value Unwrapping
Getting the associated value from an enum case can be a real pain, so there are properties for each case to unwrap the value.
If you have the example JSON above, it is an .object
case.
You can use the .object
property to get the [String: JSON]
value it wraps:
json.object // [String: JSON]?
There are also properties for .null
, .string
, .bool
, .int
, .float
, .double
, and .array
.
Be sure to read the docs for the .null
property.
These properties also have setters. They let you set the value of the current JSON
case.
They will set the case regardless the current type, so if the case is a .bool
,
you can use .string
and the case will be changed to a .string
case.
var json = JSON.bool(true)
json.string = "Fizz Buzz"
print(json) // "\"Fizz Buzz\""
Dynamic Access
JSON
supports @dynamicMemberLookup
, so it is really easy to access values your JSON objects/arrays:
let firstname = json.users.0.name.first.string
This also works for setting JSON values:
json.users.0.name.first = "Tanner"
-
Gets the value of a
.null
case.You will always get
nil
from this property. This is because the JSON case is itself.null
, or it isn’t so conversion failed and you getnil
.The
Wrapped
type isNever
so the compiler can gurantee that the value isnil
.Declaration
Swift
public var null: Optional<Never> { get set }
-
Accesses the value of a
.bool
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var bool: Bool? { get set }
-
Accesses the value of a
.string
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var string: String? { get set }
-
Accesses the value of a
Number.int
case wrapped in a.number
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var int: Int? { get set }
-
Accesses the value of a
Number.float
case wrapped in a.number
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var float: Float? { get set }
-
Accesses the value of a
Number.double
case wrapped in a.number
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var double: Double? { get set }
-
Accesses the value of a
Number.decimal
case wrapped in a.number
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var decimal: Decimal? { get set }
-
Accesses the value of an
.array
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var array: [JSON]? { get set }
-
Accesses the value of an
.object
case.The setter will set the JSON case regardles the current type.
Declaration
Swift
public var object: [String : JSON]? { get set }
-
Converts a non-optiona JSON case to an optional JSON case.
If the JSON case is
.null
, thennil
will be returned. Otherwise the JSON case is returned. This allows you to unwrap a case to make sure it isn’tnull
:if let value = json.optional { // ... }
Declaration
Swift
public var optional: Optional<JSON> { get }
-
A boolean JSON value.
{ "fizz": true, "buzz": false }
Declaration
Swift
case bool(Bool)
-
A string JSON value.
{ "foo": "bar" }
Declaration
Swift
case string(String)
-
A JSON array of values.
[ "foo", "bar", 1997, ]
Declaration
Swift
case array([JSON])
-
A JSON object which maps string keys to JSON values.
{ "foo: "bar", "fizz": true, "bar": [98, 97, 114] }
Declaration
Swift
case object([String : JSON])
-
Creates a
JSON
instance with the.null
case.Declaration
Swift
public init()
-
Creates a
JSON
instance with the.number(Number.int)
case.Declaration
Swift
public init(_ int: Int)
Parameters
int
The
Int
held by the.int
case. -
Creates a
JSON
instance with the.number(Number.float)
case.Declaration
Swift
public init(_ float: Float)
Parameters
float
The
Float
held by the.float
case. -
Creates a
JSON
instance with the.number(Number.double)
case.Declaration
Swift
public init(_ double: Double)
Parameters
double
The
Double
held by the.double
case. -
Creates a
JSON
instance with the.number(Number.decimal)
case.Declaration
Swift
public init(_ decimal: Decimal)
Parameters
decimal
The
Decimal
held by the.decimal
case. -
Creates a
JSON
instance with the.number
case.Declaration
Swift
public init<I>(_ fwi: I) where I : FixedWidthInteger
Parameters
fwi
A fixed-width integer which is converted to an
Int
and then passed into a.number(.int)
case. -
Creates a
JSON
instance from raw JSON data.Declaration
Swift
public init(data: Data) throws
Parameters
data
The JSON data to decode to
JSON
.
-
Gets the JSON value for a given key.
Complexity
O(n), where n is the number of elements in the JSON array you are accessing object values from. More often though, you are accessing object values via key, and that is O(1).Most of the time, the member passed in with be a
String
key. This will get a value for an object key:json.user.first_name // .string("Tanner")
However,
Int
members are also supported in that case of aJSON
array:json.users.0.age // .number(.int(42))
Declaration
Swift
public subscript(dynamicMember member: String) -> JSON { get set }
Parameters
member
The key for JSON objects or index for JSON arrays of the value to get.
-
Accesses the
JSON
value at a given key/index path.Complexity
O(n) where n is the number of elements in the path.To get the value,
.get(_:)
is used. To set the value,.set(_:to:)
is used.Declaration
Swift
public subscript(path: String...) -> JSON { get set }
Parameters
path
The key/index path to access.
Return Value
Thw JSON value(s) found at the path passed in.
-
Gets the JSON at a given path.
Complexity
O(n) where n is the number of elements in the path.If an
.array
case is found, the path key will be converted to an index and the array element at that index will be returned. If key to index conversion fails, or the index it outside the range of the array,.null
is returned.Declaration
Swift
public func get(_ path: [String]) -> JSON
Parameters
path
The keys and indexes to the desired JSON value(s).
Return Value
Thw JSON value(s) found at the path passed in. You will get a
.null
case if no JSON is found at the given path. -
Sets the value of an object key or array index.
Complexity
O(n), where n is the number of elements in the
path
. This method is recursive, so you may have adverse performance for long paths.Declaration
Swift
public mutating func set<Path>(_ path: Path, to json: JSON) where Path : Collection, Path.Element == String
Parameters
path
The path of the value to set.
json
The JSON value to set the index or key to.
-
Removes a key/value pair from an object at a given path.
The
JSON
type convertsnil
to it’s.null
case, so if you try to remove a value like this:json["foo", "bar"] = nil
You just set the object’s property to
null
:{ "foo": { "bar": null } }
To actually remove a property from an object, you use
.remove(_:)
with the path to the property to remove:json.remove(["foo", "bar"])
Will result in this json structure:
{ "foo": {} }
Complexity
O(n), where n is the number of elements in the path to remove. Keep in mind that this method is recursive, so each succesive eleemnt in the path will add another call to the stack.
Declaration
Swift
public mutating func remove<Path>(_ path: Path) where Path : Collection, Path.Element == String
Parameters
path
The key path to the json property to remove.
-
See
CustomStringConvertible.description
.This textal representation is compressed, so you might need to prettify it to read it.
Declaration
Swift
public var description: String { get }
-
Indicates whether this case is a
.null
.Declaration
Swift
public var isNull: Bool { get }
-
Indicates whether this case is a
.bool
.Declaration
Swift
public var isBool: Bool { get }
-
Indicates whether this case is a
.string
.Declaration
Swift
public var isString: Bool { get }
-
Indicates whether this case is a
.number
.Declaration
Swift
public var isNumber: Bool { get }
-
Indicates whether this case is a
.number(.int)
.Declaration
Swift
public var isInt: Bool { get }
-
Indicates whether this case is a
.number(.float)
.Declaration
Swift
public var isFloat: Bool { get }
-
Indicates whether this case is a
.number(.double)
.Declaration
Swift
public var isDouble: Bool { get }
-
Indicates whether the case is a
.object
.Declaration
Swift
public var isObject: Bool { get }
-
Indicates whether the case is an
.array
.Declaration
Swift
public var isArray: Bool { get }
-
See
Decodable.init(from:)
.Declaration
Swift
public init(from decoder: Decoder) throws
-
See
Encodable.encode(to:)
.Declaration
Swift
public func encode(to encoder: Encoder) throws
-
A generic
See moreCodingKey
type that supports any value.Declaration
Swift
public struct CodingKeys : CodingKey
-
Creates a
JSON
instance with the.null
case.Declaration
Swift
public init(nilLiteral: ())
-
Creates a
JSON
instance with the.number(Number.int)
case.Declaration
Swift
public init(integerLiteral value: Int)
Parameters
value
The
Int
wrapped by the.int
case.
-
Creates a
JSON
instance with the.number(Number.double)
case.Declaration
Swift
public init(floatLiteral value: Double)
Parameters
value
The
Double
wrapped by the.double
case.
-
Creates a
JSON
instance with the.array
case.Declaration
Swift
public init(arrayLiteral elements: SafeJSONRepresentable...)
Parameters
elements
The array elements, which will be converted to their
JSON
representation, wrapped by the.array
case.
-
Creates a
JSON
instance with the.array
case.Declaration
Swift
public init(dictionaryLiteral elements: (String, SafeJSONRepresentable)...)
Parameters
elements
The dictionary key/value pairs wrapped in the
.object
case, with the values converted to theirJSON
representations.
-
Declaration
Swift
public var json: JSON { get }
-
Declaration
Swift
public init?(json: JSON)