[当我通过urlSession向服务器发出api请求时,可能会收到json之类的信息
{
"movie": "Avengers",
"director": "Joss Whedon",
}
或这样
{
"apiKey": "invalid"
}
我有两个要像这样保存的结构
struct Movie: Codable {
let request: String
let director: String
init(movie:String, director:Sring) {
self.movie = movie
self.director = director
}
}
struct Valid: Codable {
let apiKey: String
init(apiKey:String) {
self.apiKey = apiKey
}
}
基于响应,我想解码为第一个结构或第二个结构。怎么做。
if let url = URL(string: "myurl.com") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
guard let json = data as? [String:AnyObject] else {
return
}
do {
if let movie = json["movie"]{
//moview is there. so you can decode to your movie struct
let res = try JSONDecoder().decode(Movie.self, from: data)
}else{
//move is not there.it means error
let res = try JSONDecoder().decode(Valid.self, from: data)
}
} catch let error {
print(error)
}
}
}.resume()
}
首先,解析上述2个[[JSON响应的Codable
类型应该看起来像,
struct Movie: Decodable {
let movie: String
let director: String
}
struct Valid: Decodable {
let apiKey: String
}
无需显式创建init()
。Codable
将自动处理。下一步,您需要创建另一个可以处理两个响应的
Codable
类型,即
enum Response: Decodable { case movie(Movie) case valid(Valid) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() do { let data = try container.decode(Movie.self) self = .movie(data) } catch { let data = try container.decode(Valid.self) self = .valid(data) } } }
现在,您可以像这样解析JSON
data
,do {
let response = try JSONDecoder().decode(Response.self, from: data)
print(response)
} catch {
print(error)
}