无法使用类型为'(GenericDM.Type,from:String?)'的参数列表调用'decode'

时间:2019-01-28 21:48:53

标签: json swift

我一直在使用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)

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

但是,我得到无法使用类型为'(GenericDM.Type,from:String?)'的参数列表调用'decode',我不明白为什么。

有人有什么主意吗?

1 个答案:

答案 0 :(得分:0)

假设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)
}