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

Swift使用JSONSerialization转换字典时如何忽略不兼容类型避免异常

问题解决方法

JSONSerialization本身没有内置忽略不兼容类型的配置项,默认只要待序列化的对象中存在非JSON兼容类型(包括NSData、自定义类实例等),就会直接抛出异常,无法仅保留兼容值继续序列化。

你不需要手动遍历复杂的嵌套结构,只需写两个通用的递归扩展,就可以自动处理任意层级的字典、数组嵌套,过滤所有非兼容类型:

import Foundation

extension Dictionary where Key == AnyHashable, Value == Any {
    /// 递归过滤所有非JSON兼容类型,返回可直接序列化的字典
    func filteredForJSONSerialization() -> [AnyHashable: Any] {
        var validDict = [AnyHashable: Any]()
        for (key, value) in self {
            // 递归处理嵌套字典
            if let subDict = value as? [AnyHashable: Any] {
                validDict[key] = subDict.filteredForJSONSerialization()
            }
            // 递归处理嵌套数组
            else if let subArray = value as? [Any] {
                validDict[key] = subArray.filteredForJSONSerialization()
            }
            // 保留JSON兼容的基础类型
            else if value is String || value is NSNumber || value is NSNull {
                validDict[key] = value
            }
            // NSData等非兼容类型直接跳过,不写入结果
        }
        return validDict
    }
}

extension Array where Element == Any {
    /// 递归过滤数组中的非JSON兼容类型
    func filteredForJSONSerialization() -> [Any] {
        compactMap { element in
            if let subDict = element as? [AnyHashable: Any] {
                return subDict.filteredForJSONSerialization()
            } else if let subArray = element as? [Any] {
                return subArray.filteredForJSONSerialization()
            } else if element is String || element is NSNumber || element is NSNull {
                return element
            }
            return nil
        }
    }
}

使用时仅需要在序列化前调用一次扩展方法即可,不需要改动其他逻辑:

let validDictionary = inputDictionary.filteredForJSONSerialization()
do {
    let jsonData = try JSONSerialization.data(withJSONObject: validDictionary, options: [.prettyPrinted])
    // 后续处理JSON数据
} catch {
    // 此时仅会出现极端场景的报错,比如字典全为空等
    print(error.localizedDescription)
}

如果需要保留NSData的内容而非直接过滤,可以在判断逻辑中新增分支,将NSData转换为base64字符串后存入结果即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:00:02