【问题标题】:Strange error in Swift Playground while decoding REST解码 REST 时 Swift Playground 出现奇怪错误
【发布时间】:2021-02-20 03:26:09
【问题描述】:
import Foundation
import Combine

let liveSample = URL(string: "https://newsapi.org/v2/top-headlines?country=us&apiKey=<api key>")!

struct ArticleList: Codable {
    struct Article: Codable {
        struct Source: Codable {
            var id: String?
            var name: String?
        }
        var source: Source?
        var author: String?
        var title: String?
        var description: String?
        var url: URL?
        var urlToImage: URL?
        var publishedAt: Date?
        var content: String?
    }
    var status: String
    var totalResults: Int
    var articles: [Article]
}

struct Resource<T: Codable> {
    let request: URLRequest
}

extension URLSession {
    func fetchJSON<T: Codable>(for resource: Resource<T>) -> AnyPublisher<T, Error> {
        return dataTaskPublisher(for: resource.request)
            .map { $0.data }
            .decode(type: T.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }
}

var subscriber: AnyCancellable?

var resource: Resource<ArticleList> =
    Resource<ArticleList>(request: URLRequest(url: liveSample))

subscriber?.cancel()
subscriber = URLSession.shared.fetchJSON(for: resource)
    .receive(on: DispatchQueue.main)
    .sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("The publisher finished normally.")
        case .failure(let error):
            print("An error occured: \(error).")
        }
    }, receiveValue: { result in
        dump(result)
    })

我正在使用 Xcode 12 RC 生成错误:

发生错误:typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "articles", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys (stringValue: "publishedAt", intValue: nil)], debugDescription: "期望解码 Double 但找到了一个字符串/数据。",underlyingError: nil))。

【问题讨论】:

  • 请仔细阅读错误信息。这很清楚。键 articles 的数组中键 publishedAt 的值是一个字符串。要将值解码为Date,您必须添加.iso8601 日期解码策略。默认日期解码策略需要TimeInterval(又名Double)。

标签: json swift codable swift-playground


【解决方案1】:

我可以看到你在这里直接使用JSONDecoder(),在你的模型中var publishedAt: Date?是一个日期对象。

您需要先配置解码器以从字符串中解析日期然后使用它。

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601 // <------- set date decoding strategy explicitly 
extension URLSession {
    func fetchJSON<T: Codable>(for resource: Resource<T>) -> AnyPublisher<T, Error> {
        return dataTaskPublisher(for: resource.request)
            .map { $0.data }
            .decode(type: T.self, decoder: decoder)
            .eraseToAnyPublisher()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-08
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多