JSON Processing in Swift (iOS/macOS): A Complete Guide
JSON (JavaScript Object Notation) is one of the most popular data exchange formats in modern applications. In the Apple ecosystem (iOS, macOS, watchOS, tvOS), Swift provides several powerful ways to work with JSON. In this article, we will cover three main approaches: the native Codable, the low-level JSONSerialization, and the popular third-party library SwiftyJSON. You will learn how to parse, create, and process JSON in Swift with code examples.
1. Codable — The Modern Swift Standard
Starting with Swift 4, Apple introduced the Codable protocols (combining Encodable and Decodable). This is the most convenient and type-safe way to work with JSON. You simply declare a struct or class conforming to Codable and use JSONEncoder/JSONDecoder.
Example: Parsing JSON from an API Response
import Foundation
// Define a model that automatically conforms to Codablestruct User: Codable { let id: Int let name: String let email: String let isActive: Bool}
// Example JSON stringlet jsonString = """{ "id": 42, "name": "Ivan Petrov", "email": "ivan@example.com", "isActive": true}"""
// Parsingif let jsonData = jsonString.data(using: .utf8) { let decoder = JSONDecoder() do { let user = try decoder.decode(User.self, from: jsonData) print("User: \\(user.name), email: \\(user.email)") } catch { print("Decoding error: \\(error.localizedDescription)") }}Example: Creating JSON from an Object
let user = User(id: 1, name: "Anna Smirnova", email: "anna@test.com", isActive: false)let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // for pretty formatting
if let jsonData = try? encoder.encode(user), let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString)}Working with Nested Structures and Arrays
struct Company: Codable { let name: String let employees: [User]}
let companyJson = """{ "name": "TechCorp", "employees": [ {"id": 1, "name": "Oleg", "email": "oleg@tc.com", "isActive": true}, {"id": 2, "name": "Maria", "email": "maria@tc.com", "isActive": false} ]}"""
if let data = companyJson.data(using: .utf8), let company = try? JSONDecoder().decode(Company.self, from: data) { print("Company: \\(company.name), employees: \\(company.employees.count)")}2. JSONSerialization — The Classic Approach (Foundation)
Before Codable, the main tool was JSONSerialization from Foundation. It works with Foundation dictionaries and arrays ([String: Any] and [Any]). This method is useful when the JSON structure is unknown in advance or highly dynamic.
Example: Parsing with JSONSerialization
if let data = jsonString.data(using: .utf8) { do { if let dict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { let id = dict["id"] as? Int ?? 0 let name = dict["name"] as? String ?? "Unknown" print("ID: \\(id), Name: \\(name)") } } catch { print("Error: \\(error)") }}Drawback: lack of type safety — you need to manually cast types, which can lead to runtime errors. It is recommended to use Codable wherever possible.
3. SwiftyJSON — A Convenient Third-Party Library
SwiftyJSON is a popular open-source library