iOS中如何编写JSON语句:从基础到实践
在iOS开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其可读性强、解析方便,成为客户端与服务器通信、本地数据存储的常用选择,无论是接收服务器返回的数据,还是将本地数据封装后上传,都离不开JSON的编写与处理,本文将从JSON的基础语法出发,结合iOS开发中的实际场景,详细介绍如何在Swift中编写JSON语句,包括手动构建、编码与解码,以及常见问题的解决方案。
JSON基础语法回顾
在编写JSON之前,需先明确其核心语法规则,这是正确构建JSON的前提:
-
数据类型:JSON支持两种结构类型:
- 对象(Object):无序的键值对集合,以包裹,键(key)必须是字符串,值(value)可以是任意JSON支持的类型(如字符串、数字、布尔值、数组、对象或null)。
{"name":"张三","age":30}。 - 数组(Array):有序的值列表,以
[]包裹,值可以是任意JSON支持的类型。[1,"apple",true]。
- 对象(Object):无序的键值对集合,以包裹,键(key)必须是字符串,值(value)可以是任意JSON支持的类型(如字符串、数字、布尔值、数组、对象或null)。
-
值类型:JSON中的值可以是:
- 字符串(需用双引号包裹,如
"iOS") - 数字(整数或浮点数,如
18、14) - 布尔值(
true或false) - null(表示空值)
- 对象或数组(嵌套结构)
- 字符串(需用双引号包裹,如
-
注意事项:
- JSON中不能使用单引号(字符串必须用双引号),也不能使用注释。
- 键值对之间用逗号分隔,最后一个键值对后不能有多余逗号(否则会解析失败)。
iOS中编写JSON的两种方式
在iOS开发中,编写JSON主要有两种思路:
- 手动构建JSON字符串:直接通过字符串拼接生成JSON格式的内容,适用于简单、固定的数据结构。
- 使用Codable协议自动编码/解码:通过定义Swift结构体/类,利用
JSONEncoder和JSONDecoder将对象转换为JSON数据(或反之),这是现代iOS开发中更推荐的方式(避免手动拼接的繁琐与错误)。
手动构建JSON字符串
对于结构简单的JSON,可直接通过字符串拼接生成,但需注意转义特殊字符(如双引号需转义为\",换行符需转义为\n等)。
示例1:构建简单的JSON对象
假设要构建一个包含用户信息的JSON对象:{"name":"张三","age":30,"isStudent":false},可通过字符串拼接实现:
let name = "张三"
let age = 30
let isStudent = false
// 手动拼接JSON字符串
let jsonString = """
{
"name": "\(name)",
"age": \(age),
"isStudent": \(isStudent)
}
"""
print(jsonString)
输出结果:
{
"name": "张三",
"age": 30,
"isStudent": false
}
示例2:构建嵌套JSON结构
若JSON包含嵌套对象或数组(如用户地址信息),需逐层拼接:
let address = "北京市朝阳区"
let hobbies = ["阅读", "游泳", "编程"]
let nestedJsonString = """
{
"name": "李四",
"age": 25,
"address": "\(address)",
"hobbies": \(hobbies.map { "\"\($0)\"" }) // 数组元素需转为字符串并用双引号包裹
}
"""
print(nestedJsonString)
输出结果:
{
"name": "李四",
"age": 25,
"address": "北京市朝阳区",
"hobbies": ["阅读", "游泳", "编程"]
}
手动构建的优缺点
- 优点:简单直观,无需额外依赖,适合一次性、简单的JSON生成。
- 缺点:
- 数据结构复杂时,字符串拼接繁琐且易出错(如遗漏逗号、引号转义错误)。
- 无法动态校验数据的合法性(如字段类型是否匹配)。
使用Codable协议自动编码(推荐)
现代iOS开发中,Apple推荐使用Codable协议(结合JSONEncoder和JSONDecoder)处理JSON,其核心思想是:先定义Swift模型(结构体/类),再通过编码器将模型转换为JSON数据,避免手动拼接字符串。
步骤1:定义符合Codable协议的模型
根据JSON结构,定义对应的Swift结构体或类,并遵循Codable协议(Codable是Encodable和Decodable的组合,若仅需编码为JSON,可仅遵循Encodable)。
示例1:简单模型转JSON
以用户信息为例,定义模型并编码为JSON:
import Foundation
// 1. 定义模型(遵循Codable协议)
struct User: Codable {
let name: String
let age: Int
let isStudent: Bool
}
// 2. 创建模型实例
let user = User(name: "张三", age: 30, isStudent: false)
// 3. 使用JSONEncoder编码为JSON数据
do {
let jsonData = try JSONEncoder().encode(user)
// 4. 将JSON数据转为字符串(可选)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
}
} catch {
print("编码失败: \(error)")
}
输出结果(格式化后):
{"name":"张三","age":30,"isStudent":false}
示例2:嵌套模型转JSON
若JSON包含嵌套对象或数组,需在模型中定义对应的嵌套类型:
// 地址模型
struct Address: Codable {
let city: String
let district: String
}
// 用户模型(包含嵌套地址和数组)
struct AdvancedUser: Codable {
let name: String
let age: Int
let address: Address
let hobbies: [String]
}
// 创建实例
let address = Address(city: "北京", district: "朝阳")
let advancedUser = AdvancedUser(
name: "李四",
age: 25,
address: address,
hobbies: ["阅读", "游泳", "编程"]
)
// 编码为JSON
do {
let jsonData = try JSONEncoder().encode(advancedUser)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
}
} catch {
print("编码失败: \(error)")
}
输出结果:
{"name":"李四","age":25,"address":{"city":"北京","district":"朝阳"},"hobbies":["阅读","游泳","编程"]}
示例3:处理复杂类型(日期、枚举等)
JSON本身不直接支持Swift的Date、Enum等类型,需通过JSONEncoder的dateEncodingStrategy和enumEncodingStrategy进行自定义处理。
日期编码
struct Event: Codable {
let name: String
let date: Date
}
let event = Event(name: "WWDC", date: Date())
// 自定义日期编码策略(如ISO8601格式)
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
do {
let jsonData = try encoder.encode(event)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString) // 输出: {"name":"WWDC","date":"2023-10-01T12:00:00Z"}
}
} catch {
print("编码失败: \(error)")
}
枚举编码
enum Gender: String, Codable {
case male = "男"
case female = "女"
}
struct Person: Codable {
let name: String
let gender: Gender
}
let person = Person(name: "王五", gender: .male)
// 枚举直接使用原始值编码(默认行为)
do {
let jsonData = try JSONEncoder().encode(person)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString) // 输出: {"name":"王五","gender":"男"}
}
} catch {
print("编码失败: \(error)")
}
Codable方式的优缺点
- 优点:
- 代码结构清晰,模型与JSON一一对应,易于维护。
- 自动处理转义、格式化等问题,减少手动拼接错误。
- 支持动态校验数据类型(如字段类型不匹配时会抛出错误)。
- 缺点:
需提前定义模型,对于极简单的JSON(如一次性键值对



还没有评论,来说两句吧...