The fastest Swift decoding & encoding framework.
-
NotationKit
The overlay module that re-exports the complete public interface of notation kit.
-
JSONKit
The JSON related encoders and decoders.
-
AnyNotationKit (WIP)
The toolkit to dealing with
[AnyHashable: Any]
.
Notation kit only available with SPM:
-
Add the following line to the dependencies in your Package.swift file:
.package(url: "https://github.com/undevts/NotationKit.git", from: "0.3.0"),
-
Add Numerics as a dependency for your target:
.target(name: "MyTarget", dependencies: [ .product(name: "JSONKit", package: "NotationKit"), ]),
-
Add
import JSONKit
in your source code.
To decoding an entity from JSON string or data,
a class or struct just needs to implement the JSONDecodable
protocol.
JSONDecodable
has only a requirement: init(_ json: JSON)
.
In most cases, a single decoded
function is enough to use.
import JSONKit
// If your prefer string keys.
struct User: JSONDecodable {
let username: String
let age: Int
let array: [JSON]
let dictionary: [String: String]
let friends: [User]
init(_ json: JSON) {
var keyed = json.keyed()
username = keyed.decoded("username")
age = keyed.decoded("age")
array = keyed.decoded("list")
dictionary = keyed.decoded("map")
friends = keyed.decoded("friends")
}
}
// Or if your prefer typed keys.
struct User: JSONDecodable {
let username: String
let age: Int
let array: [JSON]
let dictionary: [String: String]
let friends: [User]
init(_ json: JSON) {
var keyed = json.keyed(by: CodingKeys.self)
username = keyed.decoded(.username)
age = keyed.decoded(.age)
array = keyed.decoded(.array)
dictionary = keyed.decoded(.dictionary)
friends = keyed.decoded(.friends)
}
enum CodingKeys: String, CodingKey {
case username
case age
case array = "list"
case dictionary = "map"
case friends
}
}
Now, we can convert a JSON data to the User
model with a single line code.
let result: Result<User, JSONParseError> = JSON.parse(data, as: User.self)
Any scalar types (Int, UInt, Bool, Double, String etc.) could use decoded
series method to create new scalar values, arrays or dictionarys.
For example:
-
Int:
let age: Int = json.decoded("age")
-
Int?:
let age: Int? = json.decodedValue("age")
, note the "Value" suffix. -
[Int]:
let array: [Int] = json.decoded("array")
-
[String: Int]:
let map: [String: Int] = json.decoded("map")
For performance reasons, scalar types are NOT JSONDecodable
. The above methods are directly dealt with scalar types.
So,
let age: Int? = json.decoded("age") // ❎ Age is declared optional but never will be `nil`.
let age: Int? = json.decodedValue("age") // ✅ The correct way.
Although the JSON
struct can use subscripts to get arrays or dictionarys,
the most efficient way is to use KeyedJSON
or StringedKeyJSON
.
let json: JSON = ...
var keyed = json.keyed()
let bar = keyed.decoded("bar") as String
// Same as above, with a slight performance penalty.
let foo = json["foo"].string
JSON
do provide SwiftyJSON
style API, and decoded
series method is built on top of it.
But don't use it unless there is a specific reason.
Unlike SwiftyJSON
, the scalar getters returns a non-null value, and vice versa.
let name: String = json["name"].string
let age: Int? = json["age"].intValue
JSON kit comes with standard decoder: JSONSimdDecoder
.
Just replace JSONDecoder
with JSONSimdDecoder
and things are done.
let product = try JSONDecoder().decode(GroceryProduct.self, from: json)
let product = try JSONSimdDecoder().decode(GroceryProduct.self, from: json)
Note: JSONSimdDecoder
has no support of Swift.JSONDecoder.KeyDecodingStrategy
.
-
When installing with SPM,
JSON
isclass
insteal ofstruct
. Even though the code is exactly the same and it all compiles, usingstruct
will cause crazy and weird crashes. -
There is no way to get the raw text of a number.
JSONDecoder
andCodable
is slow.Codable
API is difficult to use.- There is no fast and handy Swift JSON framework.