0

Ive got an answer from an XML API that comes back to me as a String. I need it to be an int so that i can add it to another value in laters on. Ive tried to unwrap it and read it as an int but it didnt work. Ive also tried trimming blank spaces and then unwrap it but that didnt work either.

If i set the leading let value: Int it will give me an error saying that the value is not in the correct format.

What i have so far is this:

struct HydroData: Decodable {
    let value: String
    let textTranslationId: String?
    let titleTranslationId: String?
    let style: String?
}

struct HydroResult: Decodable {
    let HydroData: [HydroData]
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        calcIndex()
       
        let url = URL(string: "https://driftsdata.statnett.no/restapi/ProductionConsumption/GetLatestDetailedOverview")!
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {
                print("No data")
                return
            }
            do {
                let result = try JSONDecoder().decode(HydroResult.self, from: data)
                if let seDesc = result.HydroData.filter({ $0.titleTranslationId == "ProductionConsumption.HydroSEDesc" }).first {
                    
                    let hydroValue = seDesc.value
                    print(seDesc.value)
                    
                    
                } else {
                    print("Error: no value")
                }
            } catch {
                print(error.localizedDescription)
            }
        }
        task.resume()    }

    func calcIndex(){
        
       let newHydro = hydroValue + 1000
        print(newHydro)
}

}
Nisse82
  • 31
  • 7

1 Answers1

0

You need to use initializer for Int that accepts String as parameter Int(). Also, I've fixed the issue you're gonna face when you try to use the Int(seDesc.value) because it contains a non-decimal-digit character. Here's the entire code:

class ViewController: UIViewController {

    var hydroValue = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        calcIndex()

        let url = URL(string: "https://driftsdata.statnett.no/restapi/ProductionConsumption/GetLatestDetailedOverview")!
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {
                print("No data")
                return
            }
            do {
                let result = try JSONDecoder().decode(HydroResult.self, from: data)
                if let seDesc = result.HydroData.filter({ $0.titleTranslationId == "ProductionConsumption.HydroSEDesc" }).first {
                    let value = seDesc.value.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
                    self.hydroValue = Int(value) ?? 0
                    print(value)
                    self.calcIndex()
                } else {
                    print("Error: no value")
                }
            } catch {
                print(error.localizedDescription)
            }
        }
        task.resume()
    }

    func calcIndex(){

        let newHydro = hydroValue + 1000
        print(newHydro)
    }
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
  • This API will also sometimes return values such as "-1 913", or an empty string, or even "-", so maybe OP needs something rather robust. I previously suggested they use the `.digits` property of this extension: https://stackoverflow.com/a/34294660/2227743 but it has the same issue as it wouldn't cover all cases. – Eric Aya Jul 19 '20 at 20:31
  • thanks for pointing this out @EricAya - ill take it into consideration for sure. currently im just trying this out for exercise in handling and parsing api responses (no real idea what to do with it). but if i get an error i know why :). is there any way of setting a "floor" of 0? – Nisse82 Jul 20 '20 at 17:17
  • @Nisse82 Have fun experimenting, best way to learn. :) About the floor: yes, and Frankenstein already did it: `self.hydroValue = Int(value) ?? 0` means that if `Int(value)` fails, the value will be 0 by default. – Eric Aya Jul 20 '20 at 17:23
  • @EricAya ahh... ok great - thanks for clarifying, makes sense to include from the get go :) – Nisse82 Jul 21 '20 at 07:39