![](/img/trans.png)
[英]How to parse this type of json format in swift 4 with decodable?
[英]How to check and cast a type to Decodable in swift
我想發出一個網絡請求,我可以在其中控制響應是 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
。
或者任何更好的解決方案來實現我想要的? 謝謝。
我建議對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
}
以 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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.