skip to Main Content

I have a struct which has "fill" value. And that value contains Int, but in one case it has String value and I don’t know how to pair that.

Here’s the decodable JSON, I’m just showing this part, because as I think that’s where the problem is. It works fine, only that fontSize gives me headache. I don’t know how to pair it.

struct Element: Codable, Identifiable{
        var text: String?
        var textArray: [String]?
        var id: String?
        var image_url: String?
        var type : String
        var zIndex : Int
        var x: Double
        var y: Double
        var width: Double?
        var height: Double?
        var fill: String?
        var fontSize: Int? <-- ISSUE
    }

And here I want to show json

This is Int:

"fontSize": 20,

This is String:

"fontSize": "1",

Both of those values in one json!

I’ve tried to use struct it doesn’t help me. Or I’m doing smt wrong. Also I’ve tried enum and still no result. Can you please tell me where my problem is.

2

Answers


  1. You need to decode fontSize manually, something like:

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        ...
        var font: Int?
        if let fontStr = try? container.decodeIfPresent(String.self, forKey: .fontSize) {
            font = Int(fontStr)
        } else if let fontInt = try? container.decodeIfPresent(Int.self, forKey: .fontSize) {
            font = fontInt
        }
        self.fontSize = font
    }
    

    Try to mock up with some sample JSON

    var json1 = """
    {
        "fontSize": 20,
    }
    """
    
    var json2 = """
    {
        "fontSize": "1",
    }
    """
    
    let element1 = try? JSONDecoder().decode(Element.self, from: json1.data(using: .utf8)!)
    let element2 = try? JSONDecoder().decode(Element.self, from: json2.data(using: .utf8)!)
    
    //Optional(20) 
    //Optional(1)
    
    Login or Signup to reply.
  2. You can use as Any for such to avoid crashing…

    import UIKit
    
    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            var model1 : Model = Model()
            model1.fontSize = 20
            
            var model2 : Model = Model()
            model2.fontSize = "30"
            
            print("model1==(model1.fontSizeAsInt)")
            print("model2==(model2.fontSizeAsInt)")
            
        }
    
    
    }
    
    class Model {
        var fontSize : Any?
        
        var fontSizeAsInt : Int {
            get {
                if let intVar : Int = fontSize as? Int {
                    return intVar
                }
                
                if let stringVar : String = fontSize as? String {
                    return Int(stringVar) ?? 0
                }
                return 0
            }
        }
        
    }
    

    Output

    model1==20
    model2==20
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search