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

Swift 4中如何解析混合数组及提取字典指定属性?

解析JSON数组中的字典字段为String类型变量

嘿,我来帮你搞定这个JSON解析的问题!既然你已经用JSONSerialization把服务器响应转成了数组,接下来就一步步把字典里的指定字段解析成String类型变量吧~

第一步:确认数组结构

首先,假设你已经把服务器返回的Data转成了[[String: Any]]类型的数组(也就是数组里每个元素都是[String: Any]字典),代码大概是这样:

do {
    guard let responseArray = try JSONSerialization.jsonObject(with: serverResponseData, options: []) as? [[String: Any]] else {
        // 处理解析失败的情况,比如打印错误提示
        print("JSON解析失败,不是预期的数组结构")
        return
    }
    // 接下来遍历数组解析每个字典
} catch {
    print("JSON序列化错误:\(error.localizedDescription)")
}

第二步:逐个解析字段为String

对于每个字典里的字段,我们需要处理两种常见情况:字段本身就是String类型,或者字段是数字类型(比如NSNumber)需要转成String,同时还要处理字段为nil的情况(避免崩溃)。

单个字段解析示例

以cedula为例,我们可以这样写:

// 先尝试转成String,失败的话看看是不是NSNumber再转成String,都不行就用空字符串兜底
let cedula = item["cedula"] as? String ?? (item["cedula"] as? NSNumber)?.stringValue ?? ""

按照这个逻辑,把你需要的所有字段都处理一遍:

for item in responseArray {
    let cedula = item["cedula"] as? String ?? (item["cedula"] as? NSNumber)?.stringValue ?? ""
    let codZona = item["codZona"] as? String ?? (item["codZona"] as? NSNumber)?.stringValue ?? ""
    let departamento = item["departamento"] as? String ?? ""
    let dirección = item["dirección"] as? String ?? ""
    let fecing = item["fecing"] as? String ?? ""
    let mesa = item["mesa"] as? String ?? (item["mesa"] as? NSNumber)?.stringValue ?? ""
    let municipio = item["municipio"] as? String ?? ""
    let puesto = item["puesto"] as? String ?? ""
    
    // 这里可以把解析好的变量用起来,比如存到数组里或者做后续逻辑
}

更规范的方式:封装成结构体

如果需要频繁使用这些数据,建议把解析逻辑封装成一个结构体,这样代码更清晰,也方便维护:

struct LocationInfo {
    let cedula: String
    let codZona: String
    let departamento: String
    let dirección: String
    let fecing: String
    let mesa: String
    let municipio: String
    let puesto: String
    
    // 从字典初始化的方法,失败返回nil
    init?(from dictionary: [String: Any]) {
        // 解析每个字段,确保非空(如果允许空值,可以把属性改成可选类型String?)
        guard let cedula = dictionary["cedula"] as? String ?? (dictionary["cedula"] as? NSNumber)?.stringValue,
              let codZona = dictionary["codZona"] as? String ?? (dictionary["codZona"] as? NSNumber)?.stringValue,
              let departamento = dictionary["departamento"] as? String,
              let dirección = dictionary["dirección"] as? String,
              let fecing = dictionary["fecing"] as? String,
              let mesa = dictionary["mesa"] as? String ?? (dictionary["mesa"] as? NSNumber)?.stringValue,
              let municipio = dictionary["municipio"] as? String,
              let puesto = dictionary["puesto"] as? String else {
            print("某个字段解析失败,跳过该条目")
            return nil
        }
        
        self.cedula = cedula
        self.codZona = codZona
        self.departamento = departamento
        self.dirección = dirección
        self.fecing = fecing
        self.mesa = mesa
        self.municipio = municipio
        self.puesto = puesto
    }
}

然后使用的时候,直接把数组转成结构体数组:

let locationInfos = responseArray.compactMap { LocationInfo(from: $0) }
// locationInfos就是解析好的[LocationInfo]数组,直接用属性访问即可,比如locationInfos[0].cedula

几个注意点

  • 字段名拼写要准确:比如dirección带重音符号,一定要和服务器返回的key完全一致,不然会解析出nil。
  • 空值处理:如果服务器可能返回nil,你可以选择用空字符串兜底,或者把结构体属性改成可选类型String?,根据业务需求来。
  • 数字转String:像cedula、mesa这类可能是数字类型返回的字段,必须处理NSNumber转String的情况,否则直接转String会得到nil。

内容的提问来源于stack exchange,提问作者Orlando Combita

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:39:12