Swift中的JSON处理(iOS/macOS):从基础到高级应用
JSON(JavaScript Object Notation)是移动端和桌面端开发中最流行的数据交换格式之一。在Swift(iOS/macOS)生态系统中,JSON处理从Codable协议(Swift 4+)到Foundation框架中的底层JSONSerialization,都实现了原生且优雅的支持。本文将解析所有关键方法,展示代码示例,并为教育网站pythonlib.ru提供实用建议。
1. 基础:Codable协议
Codable协议是Encodable和Decodable的组合。它能自动生成代码,将你的结构体和类与JSON相互转换。这是现代Swift中处理JSON的主要推荐方式。
1.1. 简单数据模型
import Foundation
struct User: Codable { let id: Int let name: String let email: String let isActive: Bool}
// JSON字符串示例let jsonString = """{ "id": 1, "name": "伊万·彼得罗夫", "email": "ivan@example.com", "isActive": true}"""
// 解码if let jsonData = jsonString.data(using: .utf8) { let decoder = JSONDecoder() if let user = try? decoder.decode(User.self, from: jsonData) { print("用户:\\(user.name),邮箱:\\(user.email)") }}1.2. 自定义键(CodingKeys)
如果JSON中的键与模型属性不同(例如JSON中使用snake_case,Swift中使用camelCase),请使用CodingKeys枚举:
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 }}
let jsonProduct = """{ "product_id": 101, "product_name": "MacBook Pro", "price": 2499.99}"""2. 处理数组和嵌套对象
JSON通常包含对象数组或嵌套结构。Codable可以轻松处理这些情况:
struct Author: Codable { let name: String let books: [Book]}
struct Book: Codable { let title: String let year: Int}
let jsonLibrary = """{ "name": "J.K.罗琳", "books": [ {"title": "哈利·波特与魔法石", "year": 1997}, {"title": "哈利·波特与密室", "year": 1998} ]}"""
if let data = jsonLibrary.data(using: .utf8) { let author = try? JSONDecoder().decode(Author.self, from: data) print("作者:\\(author?.name ?? ""),书籍数量:\\(author?.books.count ?? 0)")}3. JSONSerialization——底层方法
尽管Codable是首选方式,但有时需要处理动态或非结构化数据。在这种情况下,请使用Foundation框架中的JSONSerialization:
let jsonString = """{ "status": "success", "data": { "temperature": 22.5, "humidity": 65, "city": "莫斯科" }}"""
if let data = jsonString.data(using: .utf8) { do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { if let status = json["status"] as? String { print("状态:\\(status)") } if let dataDict = json["data"] as? [String: Any], let temp = dataDict["temperature"] as? Double { print("温度:\\(temp)°C") } } } catch { print("JSON解析错误:\\(error.localizedDescription)") }}4. 错误处理和可选值
实际的JSON数据