You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:43:47