TestsTested | ✓ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | Jun 2016 |
SPMSupports SPM | ✓ |
Maintained by Evgenii Neumerzhitckii.
JsonSwiftson is a JSON parser that exposes just a single API method map()
for mapping JSON attributes to Swift types.
The following is an example of mapping a JSON text into a Swift Person
structure.
struct Person {
let name: String
let age: Int
}
let mapper = JsonSwiftson(json: "{ \"name\": \"Peter\", \"age\": 41 }")
let person = Person(
name: mapper["name"].map() ?? "",
age: mapper["age"].map() ?? 0
)
if !mapper.ok { /* report error */ }
There are three ways you can add JsonSwiftson into your project.
Simply add JsonSwiftson.swift file to your Xcode project.
Add the following text to your Package.swift and run swift build
.
import PackageDescription
let package = Package(
name: "YourPackageName",
targets: [],
dependencies: [
.Package(url: "https://github.com/evgenyneu/JsonSwiftson.git",
versions: Version(3,0,0)..<Version(4,0,0))
]
)
Setup a previous version of the library if you use an older version of Swift.
1) Add import JsonSwiftson
to your source code if you used Carthage or CocoaPods setup.
2) Create an instance of JsonSwiftson
class and supply a JSON text for parsing.
let mapper = JsonSwiftson(json: "{ \"person\": { \"name\": \"Michael\" }}")
3) Supply the name of JSON attribute you want to get and call the map
method. The type of the JSON value is inferred from the context.
let name: String? = mapper["person"]["name"].map()
The example above mapped JSON to an optional String type. One can map to a non-optional by using the ??
operator and supplying a default value.
let name: String = mapper["person"]["name"].map() ?? "Default name"
4) Finally, check ok
property to see if mapping was successful.
if !mapper.ok { /* report error */ }
The ok
property will return false
if JSON parsing failed or the attribute with the given name was missing. You can allow the attribute to be missing by supplying the optional: true
argument to the map
method.
let name: String? = mapper["person"]["name"].map(optional: true)
Use the map
method to parse JSON to types like strings, numbers and booleans.
// String
let stringMapper = JsonSwiftson(json: "\"Hello World\"")
let string: String? = stringMapper.map()
// Integer
let intMapper = JsonSwiftson(json: "123")
let int: Int? = intMapper.map()
// Double
let doubleMapper = JsonSwiftson(json: "123.456")
let double: Double? = doubleMapper.map()
// Boolean
let boolMapper = JsonSwiftson(json: "true")
let bool: Bool? = boolMapper.map()
Use square brackets to reach JSON properties by name: mapper["name"]
.
let mapper = JsonSwiftson(json: "{ \"name\": \"Michael\" }")
let name: String? = mapper["name"].map()
One can use square brackets more than once to reach deeper JSON properties: mapper["person"]["name"]
.
let mapper = JsonSwiftson(json: "{ \"person\": { \"name\": \"Michael\" }}")
let name: String? = mapper["person"]["name"].map()
JsonSwiftson will automatically map to the arrays of strings, numbers and booleans.
// String
let stringMapper = JsonSwiftson(json: "[\"One\", \"Two\"]")
let string: [String]? = stringMapper.map()
// Integer
let intMapper = JsonSwiftson(json: "[1, 2]")
let int: [Int]? = intMapper.map()
// Double
let doubleMapper = JsonSwiftson(json: "[1.1, 2.2]")
let double: [Double]? = doubleMapper.map()
// Boolean
let boolMapper = JsonSwiftson(json: "[true, false]")
let bool: [Bool]? = boolMapper.map()
Use mapArrayOfObjects
with a closure to map array of objects.
struct Person {
let name: String
let age: Int
}
let mapper = JsonSwiftson(json:
"[ " +
"{ \"name\": \"Peter\", \"age\": 41 }," +
"{ \"name\": \"Ted\", \"age\": 51 }" +
"]")
let people: [Person]? = mapper.mapArrayOfObjects { j in
Person(
name: j["name"].map() ?? "",
age: j["age"].map() ?? 0
)
}
Tip: Use map
method instead of mapArrayOfObjects
for mapping arrays of simple values like strings, numbers and booleans.
struct Person {
let name: String
let age: Int
}
let mapper = JsonSwiftson(json: "{ \"name\": \"Peter\", \"age\": 41 }")
let person = Person(
name: mapper["name"].map() ?? "",
age: mapper["age"].map() ?? 0
)
Verify the ok
property to see if mapping was successful. Mapping fails for incorrect JSON and type casting problems.
Note: map
and mapArrayOfObjects
methods always return nil
if mapping fails.
let successMapper = JsonSwiftson(json: "\"Correct type\"")
let string: String? = successMapper.map()
if successMapper.ok { print("👏👏👏") }
let failMapper = JsonSwiftson(json: "\"Wrong type\"")
let number: Int? = failMapper.map()
if !failMapper.ok { print("🐞") }
Mapping fails by default if JSON value is null or attribute is missing.
Tip: Pass optional: true
parameter to allow missing JSON attributes and null values.
let mapper = JsonSwiftson(json: "{ }")
let string: String? = mapper["name"].map(optional: true)
if mapper.ok { print("👏👏👏") }
Use map
method with optional: true
parameter and a closure to allow empty objects.
struct Person {
let name: String
let age: Int
}
let mapper = JsonSwiftson(json: "null") // empty
let person: Person? = mapper.map(optional: true) { j in
Person(
name: j["name"].map() ?? "",
age: j["age"].map() ?? 0
)
}
if mapper.ok { print("👏👏👏") }
Use ??
operator after the mapper if you need to map to a non-optional type like let number: Int
.
let numberMapper = JsonSwiftson(json: "123")
let number: Int = numberMapper.map() ?? 0
let arrayMapper = JsonSwiftson(json: "[1, 2, 3]")
let numbers: [Int] = arrayMapper.map() ?? []
The project includes a demo app that runs performance benchmark. It maps a large JSON file containing 100 records. The process is repeated 100 times.
Here is a list of excellent libraries that can help taming JSON in Swift.
JsonSwiftson is released under the MIT License.