Swift 4 Codable - API 有时提供 Int 有时提供字符串



我现在正在运行Codables。但是 API 有一些字符串条目,如果它们为空,它们有时可能具有0Int值。我在这里搜索并找到了这个: Swift 4 可编码 - 布尔值或字符串值 但我无法让它运行

我的结构

struct check : Codable {
let test : Int
let rating : String?  
}

评级大多数时候是类似于"1Star".但是如果没有评级,我会0int 回来。

我像这样解析数据:

enum Result<Value> {
case success(Value)
case failure(Error)
}
func checkStar(for userId: Int, completion: ((Result<check>) -> Void)?) {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "xyz.com"
urlComponents.path = "/api/stars"
let userIdItem = URLQueryItem(name: "userId", value: "(userId)")
urlComponents.queryItems = [userIdItem]
guard let url = urlComponents.url else { fatalError("Could not create URL from components") }
var request = URLRequest(url: url)
request.httpMethod = "GET"

let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = [
"Authorization": "Bearer (keytoken)"
]
let session = URLSession(configuration: config)
let task = session.dataTask(with: request) { (responseData, response, responseError) in
DispatchQueue.main.async {
if let error = responseError {
completion?(.failure(error))
} else if let jsonData = responseData {
// Now we have jsonData, Data representation of the JSON returned to us
// from our URLRequest...
// Create an instance of JSONDecoder to decode the JSON data to our
// Codable struct
let decoder = JSONDecoder()
do {
// We would use Post.self for JSON representing a single Post
// object, and [Post].self for JSON representing an array of
// Post objects
let posts = try decoder.decode(check.self, from: jsonData)
completion?(.success(posts))
} catch {
completion?(.failure(error))
}
} else {
let error = NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey : "Data was not retrieved from request"]) as Error
completion?(.failure(error))
}
}
}
task.resume()
}

正在加载它:

func loadStars() {
checkStar(for: 1) { (result) in
switch result {
case .success(let goo):
dump(goo)
case .failure(let error):
fatalError(error.localizedDescription)
}
}
}

我希望有人可以在那里帮助我,因为我不完全确定这种解析等是如何工作的。

你可以实现自己的解码init方法,从解码容器中获取每个类属性,在本节中,让你的逻辑处理"rating"是Int还是String,最后对所有必需的类属性进行签名。

这是我制作的一个简单的演示:

class Demo: Decodable {
var test = 0
var rating: String?
enum CodingKeys: String, CodingKey {
case test
case rating
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let test = try container.decode(Int.self, forKey: .test)
let ratingString = try? container.decode(String.self, forKey: .rating)
let ratingInt = try? container.decode(Int.self, forKey: .rating)
self.rating = ratingString ?? (ratingInt == 0 ? "rating is nil or 0" : "rating is integer but not 0")
self.test = test
}
}
let jsonDecoder = JSONDecoder()
let result = try! jsonDecoder.decode(Demo.self, from: YOUR-JSON-DATA)
  • 如果评级API的值是普通字符串,您将根据需要获得它。
  • 如果评级 API 的值为 0,则评级将等于"评级为 nil 或 0">
  • 如果评级 API 的值是其他整数,则评级将为"评级是整数但不是 0">

您可以修改解码的"评级"结果,这应该很容易。

希望这能给你一点帮助。 :)

有关更多信息:Apple 的编码和解码文档

相关内容

  • 没有找到相关文章

最新更新