JSON Processing in Swift (iOS/macOS): Complete Guide
JSON (JavaScript Object Notation) is the main data exchange format in modern iOS/macOS applications. Swift provides a powerful set of tools for working with JSON, ranging from built-in Codable protocols to third-party libraries that simplify parsing and serialization. In this article, we will thoroughly examine all the main ways to process JSON in Swift for Apple platforms.
Built-in JSON Support: Codable (Swift 4+)
Starting with Swift 4, Apple introduced the Codable protocols (combining Encodable and Decodable), which allow automatic conversion of custom data types to and from JSON without writing boilerplate code.
Basic JSON Decoding Example
import Foundation
// 1. Define the data modelstruct User: Codable { let id: Int let name: String let email: String let isActive: Bool}
// 2. JSON stringlet jsonString = """{ "id": 1, "name": "Ivan Petrov", "email": "ivan@example.com", "isActive": true}"""
// 3. Decodeif 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)") }}Encoding an Object to JSON
let newUser = User(id: 2, name: "Maria Sidorova", email: "maria@example.com", isActive: false)
let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // for readable output
do { let jsonData = try encoder.encode(newUser) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Encoding error: \\(error)")}Working with snake_case Keys and Custom Strategies
Often JSON comes with keys in snake_case style (e.g., first_name), while Swift properties are written in camelCase (firstName). This is solved with one line:
decoder.keyDecodingStrategy = .convertFromSnakeCaseencoder.keyEncodingStrategy = .convertToSnakeCaseJSONSerialization — Low-Level Work
For cases where the JSON structure is unknown in advance or flexibility is required, JSONSerialization from Foundation is used:
if let jsonData = jsonString.data(using: .utf8) { do { if let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] { let name = jsonDict["name"] as? String ?? "" let age = jsonDict["age"] as? Int ?? 0 print("Name: \\(name), Age: \\(age)") } } catch { print("Error: \\(error)") }}This method returns Any, so type casting is required. It is suitable for dynamic data but is less type-safe.
Third-Party Libraries
Despite the power of built-in tools, there are popular libraries that simplify working with JSON in Swift:
1. SwiftyJSON
One of the most popular libraries. It allows accessing JSON elements via subscripts and automatically handles optional values.
// Installation via Swift Package Manager: https://github.com/SwiftyJSON/SwiftyJSONimport SwiftyJSON
let json = JSON(parseJSON: jsonString)let userName = json["name"].stringValuelet userEmail = json["email"].string ?? "not specified"print("Name: \\(userName), Email: \\(userEmail)")
// Working with nested objectslet address = json["address"]["city"].stringValue2. ObjectMapper
A library for mapping JSON to objects and back. Requires