How To Parse JSON in Swift Using Codable and JSONSerialization

This post presents the following code examples for parsing JSON and encoding JSON in Swift without third-party packages or frameworks:

  1. Decode A Struct From JSON Using JSONDecoder
  2. Encode A Struct To JSON Using JSONEncoder
  3. Swift Dictionary and NSDictionary to JSON
  4. Swift Array and NSArray to JSON
  5. Encode an NSDictionary to JSON
  6. Encode an NSArray to JSON

Decode A Struct From JSON Using JSONDecoder

The Decodable protocol enables JSON encoded data to be parsed into a Swift struct using the JSONDecoder class.

struct Candidate: Decodable {
    var name: String
    var skill: String
}

let jsonObject = "{\"name\":\"Taylor\",\"skill\":\"Swift\"}"
let jsonObjectData = jsonObject.data(using: .utf8)!

// Decode the json data to a Candidate struct
let candidate = try? JSONDecoder().decode(
    Candidate.self,
    from: jsonObjectData
)

// Access properties on the decoded Candidate struct
candidate?.name // Taylor
candidate?.skill // Swift

Encode A Struct To JSON Using JSONEncoder

To encode a Swift struct to JSON, conform the struct to the Codable property.

struct Candidate: Codable {
    var name: String
    var skill: String
}

let candidate = Candidate(
    name: "Taylor",
    skill: "Swift"
)

// Encoded candidate data to JSON. Expected encoded data:
// {"name":"Taylor","skill":"Swift"}
let candidateData = try? JSONEncoder().encode(candidate)

Swift Dictionary and NSDictionary to JSON

An alternate approach to parsing JSON in Swift is to use JSONSerialization.jsonObject(with:options:), which can parse JSON and be cast to a Swift Dictionary and NSDictionary.

let jsonDict = "{\"key\":\"value\"}"
let jsonDictData = jsonDict.data(using: .utf8)!

let object = try? JSONSerialization.jsonObject(
    with: jsonDictData,
    options: []
)

// Cast to a Swift Dictionary
let dict = object as? [AnyHashable:Any]

// Cast to an NSDictionary
let nsDict = object as? NSDictionary

Swift Array and NSArray to JSON

JSONSerialization.jsonObject(with:options:) can also be used to parse JSON and be cast to a Swift Array and NSArray.

let jsonArray = "[1,2,3,4,5]"
let jsonArrayData = jsonArray.data(using: .utf8)!

let object = try? JSONSerialization.jsonObject(
    with: jsonArrayData,
    options: []
) as? [Any]

// Cast to a Swift Array
let array = object as? [Any]

// Cast to a NSArray
let nsArray = object as? NSArray

Encode an NSDictionary to JSON

Use JSONSerialization.data(withJSONObject:options:) to encode an NSDictionary as JSON data.

let nsDictionary = NSDictionary(dictionary: [
    "key": "value",
    "key2": "value2"
])

let nsDictionaryData = try? JSONSerialization.data(
    withJSONObject: nsDictionary,
    options: []
)

// Expected encoded data:
// {"key":"value","key2":"value2"}

Pass the JSONSerialization writing options flag .prettyPrinted to output JSON-encoded NSDictionary data with indentation and newline formatting.

let prettyNSDictionaryData = try? JSONSerialization.data(
    withJSONObject: nsDictionary,
    options: [.prettyPrinted]
)

// Expected encoded data:
// {
//     "key": "value",
//     "key2": "value2"
// }

Encode an NSArray to JSON

Similarly, an NSArray can be encoded as JSON data using JSONSerialization.data(withJSONObject:options:).

let nsArray = NSArray(array: [1,2,3,4,5])

let nsArrayData = try? JSONSerialization.data(
    withJSONObject: nsArray,
    options: []
)

// Expected encoded data:
// [1,2,3,4,5]

Pass the JSONSerialization writing options flag .prettyPrinted to output JSON-encoded NSArray data with indentation and newline formatting.

let prettyNSArrayData = try? JSONSerialization.data(
    withJSONObject: nsArray,
    options: [.prettyPrinted]
)

// Expected encoded data:
// [
//     1,
//     2,
//     3,
//     4,
//     5
// ]

Why Not Use SwiftyJSON and Cocoapods for parsing JSON in Swift?

Many apps do not require complex JSON manipulation beyond what Apple-provided classes like JSONSerialization allow. By implementing JSON parsing and encoding using Apple-provided classes, a developer can:

  • simplify the codebase by removing a third-party dependency like SwiftyJSON
  • reduce the binary size of the application
  • reduce risk associated with relying on third-party dependencies

JSON Encoding and Decoding in Swift

That’s it! Using JSONSerialization, JSONDecoder, and JSONEncoder you can work with JSON in Swift without any external dependencies.