我想发出一个网络请求,在其中我可以控制响应是JSON原始值[String: Any或Decodable。
示例如下:
func reqest<T>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
session.dataTask(with: request) { (data, response, error) in
if T.self is Decodable.Type {
try? JSONDecoder().decode(T.self, from: data)
} else {
try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
}
}.resume()
}然后,当我想要JSON值时,我只需要调用T作为[String: Any],或者使用任何型号的确认Decodable协议。
问题是这一行:
try? JSONDecoder().decode(T.self, from: data)如何将T转换为Decodable
我知道如何使用:
func reqest<T: Decodable >(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void)但是[String: Any]不是Decodable。
或者有什么更好的解决方案来实现我想要的?谢谢。
发布于 2020-08-27 17:41:39
我建议对reqest(endpoint:completion:)函数使用重载来实现您想要的功能。
例如,我想要的结构是这样的:
enum ResponseError: Error {
case noData
case typeMismatch
}
func reqest<T>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
baseReqest(endpoint: endpoint) { result in
switch result {
case .success(let data):
do {
guard let json = try JSONSerialization.jsonObject(with: data) as? T else {
completion(.failure(ResponseError.typeMismatch))
return
}
completion(.success(json))
} catch {
completion(.failure(error))
}
case .failure(let error):
completion(.failure(error))
}
}
}
func reqest<T: Decodable>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
baseReqest(endpoint: endpoint) { result in
switch result {
case .success(let data):
do {
let response = try JSONDecoder().decode(T.self, from: data)
completion(.success(response))
} catch {
completion(.failure(error))
}
case .failure(let error):
completion(.failure(error))
}
}
}
private func baseReqest(endpoint: EndPoint, completion: @escaping (Result<Data, Error>) -> Void) {
session.dataTask(with: request) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(ResponseError.noData))
return
}
completion(.success(data))
}.resume()
}这样,您就可以在baseReqest(endpoint:completion:)函数中使用通用的响应处理代码,并在其他两个函数中仅分离响应解析。
那么调用reqest(endpoint:completion:)函数可以是
使用[String: Any]作为响应类型的
reqest(endpoint: endpoint) { (result: Result<[String: Any], Error>) in
// Handle result
}使用[[String: Any]]作为响应类型的
reqest(endpoint: endpoint) { (result: Result<[[String: Any]], Error>) in
// Handle result
}Decodable对象作为响应类型:struct Response: Decodable {}
reqest(endpoint: endpoint) { (result: Result<Response, Error>) in
// Handle result
}发布于 2020-08-27 18:13:43
用Swift的方式来做。使用struct Codable (这给你提供了Decodable一起)。
例如:
struct testStruct: Codable {
public var testString:String!
public var testAny:Any!
init(
testString:String!,
testAny:Any!
)
{
self.testString = testString
self.testAny = testAny
}然后使用以下代码对其进行初始化:
var testStructToUse:[testStruct] = []在这里,您可以使用append方法填充它:
testStructToUse.append(testStruct(testString: "any String", testAny: "any value"))并使用JSONencoder编码
let jsonData = try JSONEncoder().encode(testStruct)https://stackoverflow.com/questions/63608606
复制相似问题