Mobile Development 18 min read

Using Swift Codable for JSON Encoding and Decoding: Features, Tips, and Advanced Scenarios

This article explains how Swift's Codable protocol simplifies converting between JSON and native data structures, covering basic usage, handling nested objects, optional values, key mapping, date formats, enums, dynamic payloads, and custom types for robust iOS development.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Using Swift Codable for JSON Encoding and Decoding: Features, Tips, and Advanced Scenarios

Swift 4 introduced the Codable protocol to replace NSCoding, allowing structs, enums, and classes to be easily serialized to and from JSON and other formats.

By conforming to Codable, a type automatically gets init(from:) and encode(to:) implementations, reducing boilerplate code.

Example of a simple Student struct and how to make it Codable:

struct Student: Codable {
    var id: String
    var name: String
    var grade: Int
}

Decoding JSON to a Swift type uses JSONDecoder :

let student = try JSONDecoder().decode(Student.self, from: jsonData)
print(student)

Encoding a Swift value back to JSON uses JSONEncoder :

let jsonData = try JSONEncoder().encode(student)
let jsonString = String(data: jsonData, encoding: .utf8)

For nested objects, arrays, and dictionaries, Codable works as long as the contained types also conform to Codable. Example of a Class containing an array of Student :

struct Class: Codable {
    var classNumber: String
    var students: [Student]
}

Optional properties handle missing or null values; making the property optional lets the decoder produce nil for empty objects or null.

class SourceFeed: Codable {
    var feedId: String?
    var title: String?
}

Key mismatches between JSON snake_case and Swift camelCase can be solved with JSONDecoder.keyDecodingStrategy or by defining a CodingKeys enum.

var decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
private enum CodingKeys: String, CodingKey {
    case chatMessage = "chat_message"
}

Date values can be decoded by setting JSONDecoder.dateDecodingStrategy to .iso8601 , .secondsSince1970 , or a custom DateFormatter .

decoder.dateDecodingStrategy = .iso8601

Enums can conform to Codable by providing raw values, allowing JSON strings or integers to map directly to Swift enum cases.

enum FeedTemplate: String, Codable {
    case video = "video"
    case pic = "pic"
    case link = "link"
}

Dynamic payloads where only one of several possible sub‑objects is present require custom init(from:) and encode(to:) implementations, using decodeIfPresent for optional sub‑objects.

struct Feed: Codable {
    var template: FeedTemplate
    var videoFeed: VideoFeed?
    var picFeed: PicFeed?
    var linkFeed: LinkFeed?
    // custom init omitted for brevity
}

When a property’s type does not itself conform to Codable (e.g., CLLocationCoordinate2D ), you can encode/decode its constituent values manually or wrap it in a Codable struct.

struct Destination: Codable {
    var location: Coordinate
    var name: String
}
struct Coordinate: Codable {
    let latitude, longitude: Double
}

Overall, Codable dramatically simplifies JSON handling in Swift, reducing boilerplate and improving safety across a wide range of use‑cases.

Mobile DevelopmentiOSencodingJSONSwiftdecodingCodable
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.