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

如何为所有JSONEncoder和JSONDecoder设置全局日期编码/解码策略?

修改JSONDecoder/JSONEncoder默认日期解析策略的可行方案

首先明确:直接修改JSONDecoder.DateDecodingStrategy这类类型属性是行不通的——Swift的JSONDecoder和JSONEncoder的日期策略是实例属性,并非可修改的类型属性。下面提供几种实用的替代方案,帮你避免重复设置策略:

1. 创建全局共享实例

定义预先配置好ISO8601策略的全局解码器/编码器,后续所有请求直接复用:

// 全局共享JSONDecoder
let sharedJSONDecoder: JSONDecoder = {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    return decoder
}()

// 全局共享JSONEncoder
let sharedJSONEncoder: JSONEncoder = {
    let encoder = JSONEncoder()
    encoder.dateEncodingStrategy = .iso8601
    return encoder
}()

使用示例:

URLSession.shared.dataTaskPublisher(for: request)
    .receive(on: DispatchQueue.main)
    .tryMap(handleHTTPOutput)
    .decode(type: [TaskModel].self, decoder: sharedJSONDecoder)
    // 后续处理逻辑...

2. 扩展自定义初始化器

给JSONDecoder和JSONEncoder添加便捷初始化方法,一键生成带ISO8601策略的实例:

extension JSONDecoder {
    convenience init(useISO8601DateStrategy: Bool = true) {
        self.init()
        if useISO8601DateStrategy {
            dateDecodingStrategy = .iso8601
        }
    }
}

extension JSONEncoder {
    convenience init(useISO8601DateStrategy: Bool = true) {
        self.init()
        if useISO8601DateStrategy {
            dateEncodingStrategy = .iso8601
        }
    }
}

使用示例:

// 默认启用ISO8601策略
let decoder = JSONDecoder()
// 临时关闭策略:let decoder = JSONDecoder(useISO8601DateStrategy: false)

URLSession.shared.dataTaskPublisher(for: request)
    .receive(on: DispatchQueue.main)
    .tryMap(handleHTTPOutput)
    .decode(type: [TaskModel].self, decoder: decoder)
    // 后续处理逻辑...

3. 扩展URLSession简化请求(进阶)

如果项目中大量使用网络请求,可以直接扩展URLSession,内置带ISO8601策略的解码逻辑:

extension URLSession {
    func dataTaskPublisher<T: Decodable>(for request: URLRequest, decodeTo type: T.Type) -> AnyPublisher<T, Error> {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        
        return self.dataTaskPublisher(for: request)
            .receive(on: DispatchQueue.main)
            .tryMap { data, response in
                // 复用你的handleHTTPOutput逻辑
                guard let httpResp = response as? HTTPURLResponse, (200...299).contains(httpResp.statusCode) else {
                    throw URLError(.badServerResponse)
                }
                return data
            }
            .decode(type: type, decoder: decoder)
            .eraseToAnyPublisher()
    }
}

使用示例:

URLSession.shared.dataTaskPublisher(for: request, decodeTo: [TaskModel].self)
    .sink(receiveCompletion: { completion in
        // 处理完成/错误逻辑
    }, receiveValue: { tasks in
        // 处理返回的任务数据
    })
    .store(in: &cancellables)

Swift标准库没有提供修改JSONDecoder/JSONEncoder默认策略的官方接口,以上方案都是通过封装实现统一配置,彻底避免重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:23:24