Swift 4 Codable - API 有时提供 Int 有时提供 String
Posted
技术标签:
【中文标题】Swift 4 Codable - API 有时提供 Int 有时提供 String【英文标题】:Swift 4 Codable - API provides sometimes an Int sometimes a String 【发布时间】:2018-06-04 15:26:40 【问题描述】:我现在正在运行 Codables。但是 API 有一些 String 条目,如果它们为空,则有时它们的 Int
值为 0
。我在这里搜索并找到了这个:Swift 4 Codable - Bool or String values 但我无法让它运行
我的结构
struct check : Codable
let test : Int
let rating : String?
评分通常类似于"1Star"
。但如果没有评分,我会得到 0
作为 Int 回复。
我正在解析这样的数据:
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(from:)
,就像您链接的问题的答案一样。
【参考方案1】:
您可以实现自己的 decode init 方法,从 decode 容器中获取每个类属性,在本节中,让您的逻辑处理“评级”是 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)
如果 rating API 的值是普通字符串,你会得到你想要的。
如果 rating API 的值为 0,则 rating 将等于“rating is nil or 0”
如果 rating API 的值为其他整数,则 rating 将为“rating is integer but not 0”
您可以修改解码后的“评分”结果,这应该很容易。
希望这能给你一点帮助。 :)
更多信息:Apple's encoding and decoding doc
【讨论】:
self.test = test doing
行是什么?
@Nxt97 它将本地 test
变量的值分配给 test
属性。 self.test
是类中的 test
属性。
哦,我的错...我尝试而不是 self.test = test
来做类似 self.rating = rating
的事情,因为我的 Codable 更大而且已经很晚了.. 但是现在一切正常!!!!谢谢你的帮助@vg0x00 你太棒了!以上是关于Swift 4 Codable - API 有时提供 Int 有时提供 String的主要内容,如果未能解决你的问题,请参考以下文章
Swift Codable:如果 API 将来可能向响应 JSON 添加更多属性,则包括枚举编码键
如何从 iOS Swift Codable 中的 API 响应通知或打印模型类上缺少的密钥?