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

Xcode Swift开发:将JSON响应转换为UIPickerView数组数据源

双UIPickerView级联选择的JSON解码问题修复

实现需求

  • 页面放置两个并排的UIPickerView,分别用于选择主类型(Type)和子类型(Subtype)
  • 两个选择器的数据源均为字符串数组,初始定义:
var typePickerData: [String] = [String]()
var subtypePickerData: [String] = [String]()
  • 主类型选择器的数据源为固定字符串数组,示例值:
typePickerData = ["Monitor","Keyboard","Mouse"]
  • 触发子类型接口请求的时机:viewDidLoad生命周期执行时、用户切换主类型选中项时
  • 接口返回子类型数据后,需要刷新子类型选择器展示最新选项

问题排查

最初实现时直接尝试将接口返回数据解码为字符串数组[String],代码如下:

let decoder = JSONDecoder()
    
if let jsonResponse = try? decoder.decode([String].self, from: data) {
        
    print("parse subtype response \(jsonResponse)")
        
    subtypePickerData = jsonResponse
    DispatchQueue.main.async {
        self.subtypePicker.reloadAllComponents()
    }
}

这段代码始终无法进入解码成功的分支,打印原始返回数据后确认根因:接口返回的不是纯字符串数组,而是携带name字段的对象数组,原始返回结构如下:

result Optional(<__NSArrayM 0x281370e70>(
{ name = Monitor; },
{ name = "AV Accessories"; },
{ name = Computer; },
{ name = "Monitor Stands"; },
{ name = "Bracket/Mount"; },
{ name = Screen; }
))

修复方案

调整解码逻辑,按照接口实际结构定义匹配的Codable模型,先将返回数据解码为模型对象,再通过map提取所有子类型的名称字段赋值给选择器数据源,最后回到主线程刷新控件即可,修正后代码:

let decoder = JSONDecoder()

if let jsonResponse = try? decoder.decode(Subtypes.self, from: data) {
    SubtypeList = jsonResponse.result
    self.subtypePickerData = SubtypeList.map{$0.Name}
    DispatchQueue.main.async {
        self.subtypePicker.reloadAllComponents()
    }
}

提示:如果接口返回的字段名和代码中命名规范不一致,可以通过Codable的CodingKeys做字段映射,避免解码失败。


内容的提问来源于stack exchange,提问作者Mike Volmar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:48:34