Converting numbers in String to Int

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:

import UIKit
import Foundation

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

}
struct HydroData {
    let value: Int
    let textTranslationId: String?
    let titleTranslationId: String?
    let style: String?
    
    enum CodingKeys: String, CodingKey {
        case value
        case textTranslationId
        case titleTranslationId
        case style
    }
}

extension HydroData: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        value = Int(try container.decode(String.self, forKey: .value)) ?? 0
        textTranslationId = try container.decode(String.self, forKey: .textTranslationId)
        titleTranslationId = try container.decode(String.self, forKey: .titleTranslationId)
        style = try container.decode(String.self, forKey: .style)
    }
}

let json = [
    "value": "12",
    "textTranslationId": "textTranslationId",
    "titleTranslationId": "titleTranslationId",
    "style": "style"
    ] as [String : Any]
let decoder = JSONDecoder()
let model = try decoder.decode(HydroData.self, from: JSONSerialization.data(withJSONObject: json, options: .prettyPrinted))
print(model.value)
print(model.textTranslationId)
print(model.titleTranslationId)
print(model.style)

thank you - worked great!

If you expect to use this pattern often, you can create a small property wrapper to avoid having to repeatedly implement the boilerplate in init(from decoder: Decoder)

@propertyWrapper
struct StringDecodable<Wrapped: LosslessStringConvertible>: Decodable {
    let wrappedValue: Wrapped

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let string = try container.decode(String.self)
        if let value = Wrapped(string) {
            wrappedValue = value
        } else {
            throw DecodingError.dataCorruptedError(
                in: container,
                debugDescription: "Value \(string) is not convertible to \(Wrapped.self)"
            )
        }
    }
}

It allows you to define your models like so:

struct HydroData: Decodable {
    @StringDecodable var value: Int
    let textTranslationId: String?
    let titleTranslationId: String?
    let style: String?
}
1 Like

Got it, Thanks!

Terms of Service

Privacy Policy

Cookie Policy