【问题标题】:Cannot invoke 'decode' with an argument list of type '(GenericDM.Type, from: String?)'无法使用类型为“(GenericDM.Type,来自:String?)”的参数列表调用“解码”
【发布时间】:2019-01-28 21:48:53
【问题描述】:

我一直在使用 app.quicktype.io 来生成解码 JSON 的代码。我现在面临一个我以前从未见过的问题。

首先,我有这个简单的结构:

import Foundation

struct GenericDM: Codable {
    let status, statusMessage: String
    let result: [Result]

    enum CodingKeys: String, CodingKey {
        case status
        case statusMessage = "status_message"
        case result
    }
}

struct Result: Codable {
    let applicationID, applicationName, applicationType, suFirstName: String
    let suMiddleName, suLastName, suAge, suDob: String
    let suRace: String
    let suAddress: SuAddress
    let createdTime, updatedTime: Int

    enum CodingKeys: String, CodingKey {
        case applicationID = "application_id"
        case applicationName = "application_name"
        case applicationType = "application_type"
        case suFirstName = "su_first_name"
        case suMiddleName = "su_middle_name"
        case suLastName = "su_last_name"
        case suAge = "su_age"
        case suDob = "su_dob"
        case suRace = "su_race"
        case suAddress = "su_address"
        case createdTime = "created_time"
        case updatedTime = "updated_time"
    }
}

struct SuAddress: Codable {
    let addrLine1, addrLine2, stName, addrCity: String
    let addrState, addrCounty, addrPin: String

    enum CodingKeys: String, CodingKey {
        case addrLine1 = "addr_line_1"
        case addrLine2 = "addr_line_2"
        case stName = "st_name"
        case addrCity = "addr_city"
        case addrState = "addr_state"
        case addrCounty = "addr_county"
        case addrPin = "addr_pin"
    }
}

func newJSONDecoder() -> JSONDecoder {
    let decoder = JSONDecoder()
    if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
        decoder.dateDecodingStrategy = .iso8601
    }
    return decoder
}

func newJSONEncoder() -> JSONEncoder {
    let encoder = JSONEncoder()
    if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
        encoder.dateEncodingStrategy = .iso8601
    }
    return encoder
}

// MARK: - URLSession response handlers

extension URLSession {
    fileprivate func codableTask<T: Codable>(with url: URL, completionHandler: @escaping (T?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        return self.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else {
                completionHandler(nil, response, error)
                return
            }
            completionHandler(try? newJSONDecoder().decode(T.self, from: data), response, nil)
        }
    }

    func genericDMTask(with url: URL, completionHandler: @escaping (GenericDM?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        return self.codableTask(with: url, completionHandler: completionHandler)
    }
}

然后,我读取一个 JSON 文件并尝试解码来自不同类的数据:

    let bundle = Bundle.main
    let path = bundle.path(forResource: "MockGenericData", ofType: "json")
    let jsonData = try? String.init(contentsOf: URL.init(fileURLWithPath: path!))
    let genericDM = try? newGenericDMJSONDecoder().decode(GenericDM.self, from: jsonData)

我暂时需要先读取该模型文件,然后才能从后端获取它。

但是,我得到 Cannot invoke 'decode' with an argument list of type '(GenericDM.Type, from: String?)',我不明白为什么。

有人知道吗?

【问题讨论】:

  • 什么是newGenericDMJSONDecoder
  • 你需要传递一个数据对象而不是一个字符串
  • 顺便说一句,将字符串对象命名为 jsonData 非常具有误导性
  • 可能不相关,但您不必使用CodingKeys 来满足您的特定需求,只需将解码器的keyDecodingStrategy 设置为convertFromSnakeCase。例如,它将 status_message 转换为 statusMessage
  • 你只需要使用 Data contentsOf URL 而不是 String init

标签: json swift


【解决方案1】:

假设decode 是正常的Decoder decode 方法。 from 参数期望 Data,而不是可选的 String

let url = Bundle.main.url(forResource: "MockGenericData", withExtension: "json")!
do {
    let jsonData = try Data(contentsOf: url)
    let genericDM = try newGenericDMJSONDecoder().decode(GenericDM.self, from: jsonData)
} catch {
    print(error)
}

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多