代码之家  ›  专栏  ›  技术社区  ›  Nxt97

swift 4可编码-api有时提供int有时提供string

  •  1
  • Nxt97  · 技术社区  · 7 年前

    我现在有密码了。但是api有一些字符串项,有时可以有 Int 价值 0 如果它们是空的。我在这里搜索发现了这个: Swift 4 Codable - Bool or String values 但我不能让它运行

    我的结构

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

    评级通常是 "1Star" . 但如果没有评分我会得到 作为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)
            }
        }
    }
    

    我希望有人能帮我,因为我不完全确定这种解析是如何工作的。

    1 回复  |  直到 7 年前
        1
  •  3
  •   vg0x00    7 年前

    您可以实现自己的decode init方法,从decode container中获取每个类属性,在这一节中,使您处理“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)
    
    • 如果rating api的值是普通字符串,您将得到它。
    • 如果等级API的值为0,则等级将等于“等级为零或0”
    • 如果rating api的值是其他整数,则rating将是“rating is integer but not 0”

    你可以修改解码的“评分”结果,这应该很容易。

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

    更多信息: Apple's encoding and decoding doc