Object Serialization in Swift: Codable, NSCoding, and JSONEncoder

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)

Serialization is the process of converting complex objects (structures, classes, instances) into a format suitable for storage or network transmission (JSON, Property List, binary data). Deserialization is the reverse process of restoring an object from this data. In Swift for iOS and macOS, there are two main approaches: the modern Codable protocol (and its components Encodable and Decodable) and the older NSCoding from the Foundation framework. In this article, we will examine both approaches in detail with code examples.



1. Codable Protocol (Recommended Approach)

Codable is a protocol that combines Encodable and Decodable. It allows you to automatically generate code for serialization and deserialization if all properties of your structure or class also conform to Codable (strings, numbers, dates, arrays, dictionaries, etc.).



1.1. Basic JSON Serialization

Let's consider a simple user structure:

import Foundation

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

// Create an instancelet user = User(id: 1, name: "Ivan Petrov", email: "ivan@example.com")

// Serialization to Data (JSON)let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // for readable output

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


1.2. Deserialization from JSON

// Suppose we have a JSON stringlet jsonString = """{    "id": 2,    "name": "Maria Smirnova",    "email": "maria@test.com"}"""

let jsonData = Data(jsonString.utf8)let decoder = JSONDecoder()

do { let decodedUser = try decoder.decode(User.self, from: jsonData) print("Name: \\(decodedUser.name), Email: \\(decodedUser.email)")} catch { print("Deserialization error: \\(error.localizedDescription)")}


1.3. Customizing Keys (CodingKeys)

If property names in Swift differ from keys in JSON, use the CodingKeys enumeration:

struct Article: Codable {    var title: String    var body: String    var publicationDate: Date

enum CodingKeys: String, CodingKey { case title case body case publicationDate = "published_at" // key in JSON }}

let articleJSON = """{"title":"Swift Codable","body":"Article text","published_at":"2024-01-15T10:00:00Z"}"""let articleData = Data(articleJSON.utf8)let decoder = JSONDecoder()decoder.dateDecodingStrategy = .iso8601 // for correct date parsing

if let article = try? decoder.decode(Article.self, from: articleData) { print("Title: \\(article.title), Date: \\(article.publicationDate)")}


1.4. PropertyListEncoder / PropertyListDecoder

For serialization to Property List format (XML or binary), use PropertyListEncoder:

let plistEncoder = PropertyListEncoder()plistEncoder.outputFormat = .xml

if let plistData = try? plistEncoder.encode(user) { // plistData can be saved to a file let plistString = String(data: plistData, encoding: .utf8) print(plistString ?? "Invalid data")}


2. NSCoding Protocol (for Classes Inheriting from NSObject)

NSCoding is a protocol from Objective-C that is still used for serializing classes, especially those working with UIKit/AppKit (e.g., UIView, UIViewController). It requires the class to inherit from NSObject and implement the encode(with:) and init?(coder:) methods.



2.1. Example of a Class with NSCoding

                    

Recommendations