Well everyone, it was fun while it lasted! As of Swift 4, the JSON situation
is vastly improved, and there’s very little practical reason to use JSONCore
any more! Please adopt the official Swift Codable protocol and use the
built-in encoder and decoder.
See the Apple documentation of Codable
for more information.
JSONCore will not be updated for Swift 4 and it will not receive any future
development.
Introduction
JSON Core is a JSON parser and serializer written using only core Swift. This
means it has no dependencies on Foundation, UIKit, AppKit or even Darwin. This
is a true parser and serializer, it doesn’t use NSJSONSerialization at all,
nor does it call out to any C JSON library.
It requires at least Xcode 8 and Swift 3. If you need Swift 2.x support, use
the 1.0.0 tag.
Why?
Performance
The Swift - Objective-C bridge is very efficient for the most part. However,
when dealing with potentially millions of object allocations, passing them back
and forth through the bridge is extremely costly. This is completely unnecessary
busywork for the CPU and is just a side effect of the fact that the standard
JSON engine for Swift today is an Objective-C class, NSJSONSerialization,
which returns Objective-C objects.
JSON Core works only on native Swift types, Array, Dictionary, Int64,
Double, and Bool, which means there’s no bridging required. It’s still a
long way off being as efficient as NSJSONSerialization in Objective-C only
mode, but it’s already considerably faster than NSJSONSerialization when used
with Swift code.
Here’s a chart showing the performance characteristics of JSON Core when parsing
an extremely large JSON file from disk. The source JSON file is generated when
running the unit test and contains an array of one million JSON objects. The
file is approximately 212MB.
Over time I’d like to improve this but at the moment I’m limited mostly by the
performance of Dictionary. It’s extremely costly to build up a Dictionary by
creating an empty one and then setting values and keys manually, but as of
Swift 2.1, there’s no other way to create a Dictionary dynamically. In
Foundation / CoreFoundation it’s possible to very quickly create an
NSDictionary using a C array of values and keys. Unless I write my own data
structure to represent JSON objects, which means giving up the advantages of
simply returning a Swift Dictionary to the caller, I’m probably not going to
get a huge amount more performance.
Be aware that if the string you pass in to JSONParser.parseData was bridged
using an NSString constructor, there’ll be serious performance ramifications.
You should be aware of what’s constructing your raw JSON data object and how
it gets initialised. You’ll get an almost 2x speed boost by sticking to String
over NSString.
Usage
let json = "{\"test\": 1}"
do {
let value = try JSONParser.parse(string: json)
// value is a JSONValue enum, which for our JSON should be
// an Object/Dictionary
guard let test = value["test"]?.int else { return }
print("test is \(test)")
} catch let err {
if let printableError = err as? CustomStringConvertible {
print("JSON parse error: \(printableError)")
}
}
Installation
via Swift Package Manager (Swift 3)
To use JSONCore as a Swift Package Manager package just add the following in
your Package.swift file.
To use JSONCore with Carthage add
You can use Carthage to install JSONCore
add the following lines to your Carthage:
github "tyrone-sudeium/JSONCore"
via Cocoapods
I’m not on CocoaPods (yet!), however, I will add support for CocoaPods
when I’m happy JSON Core is stable enough for production use.
Manual
JSON Core is just a single Swift file with zero dependencies, so feel free to
make this repo a submodule and just drop the JSONCore.swift file into your
project directly.
Other JSON Libraries
If you hate something, or everything about JSON Core, the Swift community
has you covered with plenty of alternatives.
JSON Core
Project Discontinued!
Well everyone, it was fun while it lasted! As of Swift 4, the JSON situation is vastly improved, and there’s very little practical reason to use JSONCore any more! Please adopt the official Swift
Codable
protocol and use the built-in encoder and decoder.See the Apple documentation of Codable for more information.
JSONCore will not be updated for Swift 4 and it will not receive any future development.
Introduction
JSON Core is a JSON parser and serializer written using only core Swift. This means it has no dependencies on Foundation, UIKit, AppKit or even Darwin. This is a true parser and serializer, it doesn’t use
NSJSONSerialization
at all, nor does it call out to any C JSON library.It requires at least Xcode 8 and Swift 3. If you need Swift 2.x support, use the 1.0.0 tag.
Why?
Performance
The Swift - Objective-C bridge is very efficient for the most part. However, when dealing with potentially millions of object allocations, passing them back and forth through the bridge is extremely costly. This is completely unnecessary busywork for the CPU and is just a side effect of the fact that the standard JSON engine for Swift today is an Objective-C class,
NSJSONSerialization
, which returns Objective-C objects.JSON Core works only on native Swift types,
Array
,Dictionary
,Int64
,Double
, andBool
, which means there’s no bridging required. It’s still a long way off being as efficient asNSJSONSerialization
in Objective-C only mode, but it’s already considerably faster thanNSJSONSerialization
when used with Swift code.Here’s a chart showing the performance characteristics of JSON Core when parsing an extremely large JSON file from disk. The source JSON file is generated when running the unit test and contains an array of one million JSON objects. The file is approximately 212MB.
Over time I’d like to improve this but at the moment I’m limited mostly by the performance of
Dictionary
. It’s extremely costly to build up aDictionary
by creating an empty one and then setting values and keys manually, but as of Swift 2.1, there’s no other way to create aDictionary
dynamically. In Foundation / CoreFoundation it’s possible to very quickly create anNSDictionary
using a C array of values and keys. Unless I write my own data structure to represent JSON objects, which means giving up the advantages of simply returning a SwiftDictionary
to the caller, I’m probably not going to get a huge amount more performance.Be aware that if the string you pass in to
JSONParser.parseData
was bridged using anNSString
constructor, there’ll be serious performance ramifications. You should be aware of what’s constructing your raw JSON data object and how it gets initialised. You’ll get an almost 2x speed boost by sticking toString
overNSString
.Usage
Installation
via Swift Package Manager (Swift 3)
To use JSONCore as a Swift Package Manager package just add the following in your
Package.swift
file.via Carthage
To use JSONCore with Carthage add You can use Carthage to install JSONCore add the following lines to your Carthage:
via Cocoapods
I’m not on CocoaPods (yet!), however, I will add support for CocoaPods when I’m happy JSON Core is stable enough for production use.
Manual
JSON Core is just a single Swift file with zero dependencies, so feel free to make this repo a submodule and just drop the
JSONCore.swift
file into your project directly.Other JSON Libraries
If you hate something, or everything about JSON Core, the Swift community has you covered with plenty of alternatives.
Just want the fastest parser around?
Want something quick but also does interesting things like lazy sequences?
Just want something popular?
NSJSONSerialization
)I won’t take it personally.