Object Serialization in Swift (iOS/macOS): Codable, JSON and PropertyList

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Object Serialization in Swift (iOS/macOS): Codable, JSON and PropertyList



Serialization is the process of converting data objects into a format suitable for storage or transmission (e.g., JSON, XML, Property List). In the Apple ecosystem (iOS, macOS, watchOS, tvOS), Swift provides a powerful and elegant mechanism for serialization and deserialization — the Codable protocol. In this article, we will thoroughly examine how to use Codable, JSONEncoder, PropertyListEncoder, and their counterparts for working with data.



What is Codable?

Codable is a composite protocol that combines Encodable (for encoding an object into an external format) and Decodable (for decoding from an external format into an object). If your Swift structure or class conforms to Codable, you automatically gain the ability to serialize and deserialize it.



Basic declaration:

struct User: Codable {    let id: Int    let name: String    let email: String}


All standard Swift types (String, Int, Double, Bool, Date, Data, URL, and even optional types and arrays/dictionaries) already conform to Codable.



Encoding to JSON

To encode an object into JSON, use JSONEncoder. Example:

let user = User(id: 1, name: "Ivan Petrov", email: "ivan@example.com")let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // for pretty output

do { let jsonData = try encoder.encode(user) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Encoding error: \\(error)")}


Result:

{  "id" : 1,  "name" : "Ivan Petrov",  "email" : "ivan@example.com"}


Decoding from JSON

For the reverse transformation, use JSONDecoder:

let jsonString = """{  "id": 2,  "name": "Maria Sidorova",  "email": "maria@example.com"}"""let jsonData = Data(jsonString.utf8)let decoder = JSONDecoder()

do { let decodedUser = try decoder.decode(User.self, from: jsonData) print("Decoded user: \\(decodedUser.name)")} catch { print("Decoding error: \\(error)")}


Working with Property List (plist)

For serialization into XML Property List format, use PropertyListEncoder and PropertyListDecoder. This is useful for storing data in configuration files or UserDefaults.



// Encoding to plistlet encoder = PropertyListEncoder()encoder.outputFormat = .xml

do { let plistData = try encoder.encode(user) // plistData can be saved to a file or UserDefaults} catch { print("Plist encoding error: \\(error)")}

// Decoding from plistlet decoder = PropertyListDecoder()do { let decodedUser = try decoder.decode(User.self, from: plistData) print(decodedUser)} catch { print("Plist decoding error: \\(error)")}


Custom Keys (CodingKeys)

Sometimes property names in Swift do not match keys in JSON. For this, the CodingKeys enumeration is used:

struct Product: Codable {    let productId: Int    let productName: String    let price: Double

enum CodingKeys: String, CodingKey { case productId = "product_id" case productName = "product_name" case price }}


Now JSON with keys product_id and product_name will be correctly processed.



Handling Dates and Other Special Types

By default, JSONEncoder and JSONDecoder encode dates as TimeInterval

Recommendations