如何为所有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
相关产品推荐
相关产品推荐

