Swift 4 Codable - API 有时提供 Int 有时提供 String [英] Swift 4 Codable - API provides sometimes an Int sometimes a String

查看:34
本文介绍了Swift 4 Codable - API 有时提供 Int 有时提供 String的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在运行 Codables.但是 API 有一些 String 条目,如果它们为空,有时可以具有 0Int 值.我在这里搜索并找到了这个:Swift 4 Codable - Bool or String values 但我无法让它运行

I have Codables running now. But the API has some String entries that can sometimes have an Int value of 0 if they are empty. I was searching here and found this: Swift 4 Codable - Bool or String values But I'm not able to get it running

我的结构

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

评分大部分时间类似于1Star".但是,如果没有评分,我将 0 作为 Int 返回.

Rating is most of the time something like "1Star". But if there is no rating I get 0 as Int back.

我是这样解析数据的:

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)
        }
    }
}

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

I hope someone can help me there, cause I'm not completely sure how this parsing, etc. works.

推荐答案

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

you may implement your own decode init method, get each class property from decode container, during this section, make your logic dealing with wether "rating" is an Int or String, sign all required class properties at last.

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

here is a simple demo i made:

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 是整数但不是 0"
  • 您可以修改解码后的评级"结果,这应该很容易.

    you may modify decoded "rating" result, that should be easy.

    希望对你有所帮助.:)

    hope this could give you a little help. :)

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

    这篇关于Swift 4 Codable - API 有时提供 Int 有时提供 String的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆