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

如何对键为ObjcType的Swift字典/OrderedDictionary进行JSON编解码?

实现Dictionary<ObjcType, SwiftType>及OrderedDictionary的JSON编解码

一、修复Objective-C类的序列化方法

你的ObjcType原有序列化/反序列化方法存在逻辑问题,先修正这两个方法:

// 修正序列化方法:将对象属性转为字典后再生成JSON
-(NSString*)GetJSON{
    NSError *writeError = nil;
    NSDictionary *propertyDict = @{
        @"field1": self.field1 ?: @"",
        @"field2": self.field2 ?: @"",
        @"field3": @(self.field3)
    };
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:propertyDict options:NSJSONWritingPrettyPrinted error:&writeError];
    
    if (writeError) {
        NSLog(@"JSON序列化失败: %@", writeError.localizedDescription);
        return @"";
    }
    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

// 修正反序列化方法:直接从JSON字典中读取字段,而非循环遍历
- (instancetype)initWithObject:(NSString *)jsonString {
    self = [super init];
    if (self != nil) {
        NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *error = nil;
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
        
        if (error) {
            NSLog(@"JSON解析失败: %@", error.localizedDescription);
            return nil;
        }
        
        self.field1 = jsonDict[@"field1"];
        self.field2 = jsonDict[@"field2"];
        self.field3 = [jsonDict[@"field3"] boolValue];
    }
    return self;
}

二、为ObjcType添加Swift的Codable支持

由于Objective-C类无法直接遵循Swift的Codable协议,通过Swift扩展实现该协议,复用已有的Objective-C方法:

import Foundation

extension ObjcType: Codable {
    // 编码:将ObjcType转为JSON字符串后写入编码器
    public func encode(to encoder: Encoder) throws {
        let jsonString = self.getJSON() // Objective-C方法名在Swift中自动转为小驼峰
        var container = encoder.singleValueContainer()
        try container.encode(jsonString)
    }
    
    // 解码:从JSON字符串初始化ObjcType实例
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let jsonString = try container.decode(String.self)
        
        guard let instance = ObjcType(object: jsonString) else {
            throw DecodingError.dataCorruptedError(
                in: container,
                debugDescription: "无法通过JSON字符串初始化ObjcType实例"
            )
        }
        self = instance
    }
}

三、实现普通Dictionary的编解码

只要ObjcType和SwiftType都遵循Codable,Dictionary<ObjcType, SwiftType>会自动获得Codable支持,直接使用JSONEncoder/JSONDecoder即可:

// 示例SwiftType(已遵循Codable)
struct MySwiftType: Codable {
    let name: String
    let count: Int
}

// 1. 创建测试数据
let key1 = ObjcType()
key1.field1 = "key_01"
key1.field2 = "desc_01"
key1.field3 = true

let key2 = ObjcType()
key2.field1 = "key_02"
key2.field2 = "desc_02"
key2.field3 = false

let testDict: [ObjcType: MySwiftType] = [
    key1: MySwiftType(name: "test_01", count: 10),
    key2: MySwiftType(name: "test_02", count: 20)
]

// 2. 序列化
do {
    let jsonData = try JSONEncoder().encode(testDict)
    guard let jsonString = String(data: jsonData, encoding: .utf8) else {
        print("JSON数据转字符串失败")
        return
    }
    print("序列化结果:\n\(jsonString)")
} catch {
    print("序列化错误: \(error.localizedDescription)")
}

// 3. 反序列化
do {
    let jsonData = jsonString.data(using: .utf8)!
    let decodedDict = try JSONDecoder().decode([ObjcType: MySwiftType].self, from: jsonData)
    print("反序列化结果:\n\(decodedDict)")
} catch {
    print("反序列化错误: \(error.localizedDescription)")
}

四、支持OrderedDictionary

只需导入OrderedCollections模块,OrderedDictionary<ObjcType, SwiftType>同样会自动支持Codable,用法与普通字典一致:

import OrderedCollections

// 1. 创建有序字典测试数据
let orderedDict = OrderedDictionary<ObjcType, MySwiftType>()
orderedDict[key1] = MySwiftType(name: "ordered_test_01", count: 100)
orderedDict[key2] = MySwiftType(name: "ordered_test_02", count: 200)

// 2. 序列化有序字典
do {
    let orderedJsonData = try JSONEncoder().encode(orderedDict)
    guard let orderedJsonString = String(data: orderedJsonData, encoding: .utf8) else {
        print("有序字典JSON转字符串失败")
        return
    }
    print("有序字典序列化结果:\n\(orderedJsonString)")
} catch {
    print("有序字典序列化错误: \(error.localizedDescription)")
}

// 3. 反序列化有序字典
do {
    let orderedJsonData = orderedJsonString.data(using: .utf8)!
    let decodedOrderedDict = try JSONDecoder().decode(OrderedDictionary<ObjcType, MySwiftType>.self, from: orderedJsonData)
    print("有序字典反序列化结果:\n\(decodedOrderedDict)")
} catch {
    print("有序字典反序列化错误: \(error.localizedDescription)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 23:37:01