Всегда нахожу ноль при проверке Double в Swift

#swift

#swift

Вопрос:

У меня есть следующий код:

 //create an NSURL
    let url = NSURL(string: self.urlString)

    //fetch the data from the url
    URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in

        //If the retrieved information is a JSON Object, and can be treated as an NSArray...
        if let jsonObj = (try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSObject) {

            let data = jsonObj.value(forKey: "pendingloads") as! NSArray

            for item in data {

                if let itemObject = item as? NSObject {

                    print("Tons value1: (itemObject.value(forKey: "tons")!)")
                    let tons = itemObject.value(forKey: "tons") as? Double ?? nil
                    print("Tons value2: (String(describing: tons))")
  

Я делаю это, потому что у меня есть возможность получить null из этих данных. Моя проблема в том, что я всегда получаю двойное значение (когда элемент возвращает единицу) при первой печати, но ноль во второй. Это потому, что значение itemObject.value (forKey: «тонны») является необязательным?

Я попытался принудительно развернуть значение, но затем оно прерывается, когда оно равно нулю. Мне нужно, чтобы он был обнуляемым, но у меня возникли проблемы с выполнением этого всеми документированными способами. Я знаю, что на этот вопрос есть очень простой ответ, но я просто еще не нашел его. Любая помощь была бы очень признательна.

Соответствующий JSON:

 }   
   "pendingloads": [
   {
      "comment": "Test Comment",
      "hauler": "Test Hauler",
      "logs": [
          {
             "coords": "(25.123456, -120.123456)",
             "type": "auth",
             "timestamp": "2019-04-04 10:52:1554393131",
             "device_id": "DEVICE-ID-DEVICE-ID-DEVICEID"
           },
           {
             "coords": "(25.123456, -120.123456)",
             "type": "update",
             "timestamp": "2019-04-08 13:38:1554748736",
             "device_id": "DEVICE-ID-DEVICE-ID-DEVICEID"
            }
       ],
       "tons": "12.800",
       "load_id": 23,
       "requires_correction": false,
       "trailer_drop": true,
       "gross": "25600.000",
       "contract_id": 3679,
       "scaleticket": "2134098",
       "destination": "TEST DESTINATION",
       "sale_id": 3961,
       "tare": "0.000",
       "net": "25600.000",
       "cull": "157.000",
       "product": "Test Product",
       "operator_id": 2674,
       "hauler_id": 617,
       "timestamp": "2019-04-08 18:38:1554766680",
       "driver": "Terry",
       "ticket": 250,
       "product_id": 3172,
       "sale": "Test Sale",
       "trailer": "013724589"
     }
   ]
 }
  

В надежде на улучшение, вот обновленный код:

 //create a URL
    let url = URL(string: self.urlString)

    //fetch the data from the url
    URLSession.shared.dataTask(with: (url)!, completionHandler: {(data, response, error) -> Void in

        if let jsonObj = (try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as AnyObject) {

            let data = jsonObj.value(forKey: "pendingloads") as! Array<AnyObject>

            for item in data {

                let itemObject = item as AnyObject
  

Комментарии:

1. ?? nil является избыточным. И вы злоупотребляете String(describing . И вам не рекомендуется использовать value(forKey , если вы действительно не знаете и не нуждаетесь в KVC.

2. Если первая print строка не завершается сбоем, но печатаются секунды, nil тогда значение для key tons явно не является Double

3. Тогда логически значение равно String

4. OMG: as? NSObject) as NSObject?? это ужасно. Не могли бы вы, пожалуйста, добавить соответствующую часть JSON.

5. Весь код ужасает. Вы пишете нереконструированный Objective-C так, как если бы это был Swift. Вы не должны использовать NSObject, JSONSerialization, NSURL или value(forKey:) .

Ответ №1:

Вы можете попробовать

 struct Root: Codable {
    let pendingloads: [Pendingload]
}

struct Pendingload: Codable {
    let comment, hauler: String
    let logs: [Log]
    let tons: String
    let loadId: Int
    let requiresCorrection, trailerDrop: Bool
    let gross: String
    let contractId: Int
    let scaleticket, destination: String
    let saleId: Int
    let tare, net, cull, product: String
    let operatorId, haulerId: Int
    let timestamp, driver: String
    let ticket, productId: Int
    let sale, trailer: String

}

struct Log: Codable {
    let coords, type, timestamp, deviceId: String 
}
  

  let url = URL(string: self.urlString)! 

 URLSession.shared.dataTask(with:url) { (data, response, error) in 
    guard let data = data else { return }
    do {
        let res = JSONDecoder()
        res.keyDecodingStrategy = .convertFromSnakeCase
        let ss = try res.decode(Root.self, from:data)
        print(ss)
    }
    catch {
        print(error)
    }

}.resume()