如何从JSON响应中获取signal值?iOS POST请求技术问询
如何从JSON响应中提取
signal值 首先先帮你修正下给出的JSON响应格式——原示例里用数组符号[]包裹键值对是错误的,正确的JSON结构应该是对象(用大括号{}),同时键值对要用冒号:分隔,字符串用双引号,修正后大概是这样:
{ "status": 200, "data": { "in_time": "12:00 PM", "out_time": "", "signal": "01" }, "Message": "Enable out time" }
接下来基于Swift语言,给你两种提取signal的方案:
方式一:用JSONSerialization(和你现有代码兼容)
你当前的请求代码用了JSONSerialization,那可以在请求的回调里继续用这个方式解析,逐层取出signal:
// 补全你的请求代码,添加URLSession任务 let parameters = ["emp_id": self.att_emp_id] var request = URLRequest(url: url!) request.httpMethod = "POST" request.httpBody = try? JSONSerialization.data(withJSONObject: parameters) // 别忘了设置请求头,告诉服务器你发的是JSON request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 发起请求并处理响应 let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { print("请求出错:\(error?.localizedDescription ?? "未知错误")") return } do { // 把数据转成JSON字典 guard let jsonDict = try JSONSerialization.jsonObject(with: data) as? [String: Any] else { print("JSON解析失败,不是预期的字典格式") return } // 取出data字段对应的子字典 guard let dataSubDict = jsonDict["data"] as? [String: Any] else { print("找不到data字段,或格式错误") return } // 提取signal值——注意这里要和JSON里的类型匹配,如果是数字就用Int,字符串就用String if let signal = dataSubDict["signal"] as? String { print("提取到signal:\(signal)") // 这里把signal传给你的业务逻辑使用 DispatchQueue.main.async { // 如果要更新UI,记得切回主线程 self.useSignalValue(signal) } } else if let signal = dataSubDict["signal"] as? Int { print("提取到数字类型的signal:\(signal)") // 处理数字类型的情况 } else { print("找不到signal字段,或类型不匹配") } } catch { print("JSON解析出错:\(error.localizedDescription)") } } task.resume()
方式二:用Codable(Swift推荐的类型安全方案)
如果你的接口响应结构固定,用Codable会更安全,避免手动类型转换的错误,步骤如下:
1. 定义对应的数据模型
根据JSON结构定义结构体,注意字段名的映射(比如JSON里的in_time对应Swift里的inTime):
struct AttendanceResponse: Codable { let status: Int let data: AttendanceData let message: String // 因为JSON里的消息字段是"Message",和属性名message不一致,需要手动映射 enum CodingKeys: String, CodingKey { case status, data case message = "Message" } } struct AttendanceData: Codable { let inTime: String let outTime: String let signal: String // 如果JSON里的signal是数字,就改成Int enum CodingKeys: String, CodingKey { case inTime = "in_time" case outTime = "out_time" case signal } }
2. 在请求回调中解析模型
// 同样补全请求代码 let parameters = ["emp_id": self.att_emp_id] var request = URLRequest(url: url!) request.httpMethod = "POST" request.httpBody = try? JSONSerialization.data(withJSONObject: parameters) request.setValue("application/json", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { print("请求出错:\(error?.localizedDescription ?? "未知错误")") return } do { // 直接把数据解码成模型对象 let attendanceResponse = try JSONDecoder().decode(AttendanceResponse.self, from: data) let signal = attendanceResponse.data.signal print("提取到signal:\(signal)") // 直接使用signal,类型完全安全 DispatchQueue.main.async { self.useSignalValue(signal) } } catch { print("模型解码出错:\(error.localizedDescription)") } } task.resume()
两种方案里,推荐用Codable,尤其是业务逻辑依赖signal值的情况下,类型安全能减少很多潜在的bug。
内容的提问来源于stack exchange,提问作者Sandesh Zote
相关产品推荐
相关产品推荐

