首页 > 解决方案 > 将模型类传递给嵌套方法时出现Swift泛型方法问题

问题描述

我有一个格式为的 json 响应

ServerResponse -> ResponseData -> 数据数组

 struct ServerResponse<T: Codable>: Codable {
    let methodName: String
    let responseCode: Int
    let responseMessage: String
    let responseData: ResponseData<T>

    enum CodingKeys: String, CodingKey {
        case methodName = "methodName"
        case responseCode = "responseCode"
        case responseMessage = "responseMessage"
        case responseData = "ResponseData"
    }
}

    struct ResponseData<T: Codable>: Codable {
        let order: Int
        let data: [T]

        enum CodingKeys: String, CodingKey {
            case order = "order"
            case data = "dataArray"
        }
    }

    struct Post: Codable {}
    struct Comment: Codable {}
    struct Comment: Codable {}

在我的响应中,数据可以是任何类型的可编码类数组,如 Post 、 comment 、 Users 等。

我创建了一些通用方法来解析响应

 func fetchGenericData2<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    self.fetchGenericData(data: data, completion: { (result:ServerResponse<T>) in
        print(result.responseData.data[0])
       // completion([result.responseData.data])
    })

}
func fetchGenericData<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    do {
        let responseObject = try JSONDecoder().decode(T.self, from: data)
        print(responseObject)
        completion(responseObject)
    } catch {
        print(error.localizedDescription)

    }
}

我通过传递我需要的可编码类来调用该方法

 self.fetchGenericData2(data: data, completion: { (response:[User]) in
                    print(response)
                })

目前我的通用模型没有达到最终方法,所以它不知道它是哪种类。

如果我直接发送最终模型,它可以正常工作,如下所示:

 self.fetchGenericData(data: data, completion: { (response:ServerResponse<User>) in
                        print(response.responseData.data)
                    })

但在这种情况下,我必须发送未抽象的 ServerResponse 类。

我如何格式化我的方法,以便我只需要使用我的最终模型名称调用一个方法,然后我就可以直接获取模型数组,例如:像这样:

 self.fetchGenericData(data: data, completion: { (response:[User]) in
                        print(response)
                    })

标签: iosswiftiphonegenericsclosures

解决方案


将数据类型更改为 T 以便对传递的内容进行解码,

struct ResponseData<T: Codable>: Codable {
    let order: Int
    let data: T

    enum CodingKeys: String, CodingKey {
        case order = "order"
        case data = "dataArray"
    }
}

现在,当您如下调用它时,它将按预期工作,

 self.fetchGenericData(data: data, completion: { (response: ServerResponse<[User]>) in
                    print(response)
                })

但是如果你想要只传递数据类型的语法,那么你必须更新你的通用方法,如下所示,

func fetchGenericData<T: Codable>(data: Data, completion: @escaping (T) -> ()) {
    do {
        let responseObject = try JSONDecoder().decode(ServerResponse <T>.self, from: data)
        print(responseObject)
        completion(responseObject)
    } catch {
        print(error.localizedDescription)

    }
}

这将允许您如下调用,

self.fetchGenericData(data: data, completion: { (response: [User]) in
                    print(response)
                })

推荐阅读