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

Swift解析数组型JSON转NSArray仅输出[字符的解决方法

问题描述

我有一个根节点为数组、内部存储多个地点信息字典的JSON文件,结构如下:

[
  {
    "tn_newsid": 144377,
    "tn_midashi": "知床半島とオホーツク海の絶景が広がる",
    "tn_name": "北海道立オホーツク公園オートキャンプ場てんとらんど",
    "tn_ktel": "0152-45-27",
    "tn_url": "",
    "tn_kdo": 144.239526856306,
    "tn_ido": 43.9880220633556,
    "tn_im1name": "144377_1.jpg",
    "tn_im2name": "144377_2.jpg",
    "tn_im3name": "144377_3.jpg",
    "tn_im4name": "144377_4.jpg",
    "type": 0,
    "nico_recommended": 0
  },
  {
    // 其余地点数据
  }
]

最初实现解析逻辑时,错误将JSONSerialization的解析结果强转为Dictionary<String,Any>,代码片段如下:

seasonInfoService.seasonServerDataJson(jsoncompleted: { () in
let responseData: Data =  self.seasonInfoService.UpdateJsonString.data(using: String.Encoding.utf8)!
    do{
        let items = try JSONSerialization.jsonObject(with: responseData) as! Dictionary<String,Any>

由于JSON文件根节点是数组(以[开头),运行时直接抛出类型转换错误:

Could not cast value of type '__NSArrayI' (0x7fff86cd0128) to 'NSDictionary' 

后续将强转类型修改为NSArray,调整后代码如下:

facilitiesService.facilitiesServerDataJson(urlToFetch: url_, jsoncompleted: { () in
let responseData: Data =  self.facilitiesService.UpdateJsonString.data(using: String.Encoding.utf8)!
    do{
        let items = try JSONSerialization.jsonObject(with: responseData) as! NSArray
        print(items)

但执行print语句时控制台仅输出[,无法获取由字典组成的完整数组。

解决方案

控制台仅输出[的核心原因不是类型转换写法错误,首先要排查数据源完整性,再调整解析逻辑的安全性:

  • 第一步:校验原始JSON字符串完整性
    先打印self.facilitiesService.UpdateJsonString的全量内容和字符长度,90%以上的同类问题是接口返回/本地读取的JSON字符串本身被截断,仅拿到了开头的[符号,没有获取到完整的数组内容。如果数据源不完整,优先修复网络请求、文件读取或字符串拼接逻辑,拿到完整合法的JSON字符串后再做解析。
  • 第二步:替换为Swift原生类型做安全解析,不要使用NSArray/NSDictionary等Objective-C遗留类型,同时移除所有强制解包(!)逻辑,避免运行时崩溃,参考写法如下:
facilitiesService.facilitiesServerDataJson(urlToFetch: url_, jsoncompleted: { [weak self] in
    guard let self = self else { return }
    // 安全转换Data,不做强制解包
    guard let responseData = self.facilitiesService.UpdateJsonString.data(using: .utf8) else {
        print("JSON字符串转Data失败,请检查编码格式")
        return
    }
    do {
        // 根节点为字典组成的数组,直接转换为Swift原生[[String: Any]]类型
        guard let items = try JSONSerialization.jsonObject(with: responseData) as? [[String: Any]] else {
            print("JSON结构不符合预期,根节点不是字典数组")
            return
        }
        print("解析完成,共获取\(items.count)个地点信息")
        // 遍历数组读取单个地点字段
        for location in items {
            let locationName = location["tn_name"] as? String ?? ""
            let latitude = location["tn_ido"] as? Double ?? 0
            let longitude = location["tn_kdo"] as? Double ?? 0
            print("地点:\(locationName),坐标:\(latitude), \(longitude)")
        }
    } catch {
        print("JSON解析失败,错误信息:\(error.localizedDescription)")
    }
})
  • 第三步:如果确认JSON字符串完整但仍解析异常,可将responseData重新转换为字符串打印,检查是否存在BOM头、不可见特殊字符导致JSON合法性校验失败。

内容的提问来源于stack exchange,提问作者Kopera Marcel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 01:24:33