UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to handle different JSON from the same URL request

Forums > Swift

Hi guys,for the same URL request I can have a different json response from the API. For success I've something like this:

{
    "error": "false",
    "value": {
        "person": {
            "personId": 1529853,
            "name": "test",
            "firstName": "tezt",
            "civility": "MR",
            "fidelityCode": "LM57CC",
            "phoneCode": "+237",
            "phoneNumber": "+237",
            "cniCode": null,
            "email": "test6@adwa.cm",
            "vipStatus": 0,
            "activationStatus": 1,
            "countryCode": 30,
            "birthDate": "2002-10-12",
            "searchStatus": "RAS"
        }
    }
}

For error I've something like this:

{
    "error": "false",
    "value": {
        "person": -1
    }
}

How can I handle it to know when it's a success or error?

3      

Basically, you need to use an enum for the "person" key with two cases have associated values of either an Int or a Person. Here is a SwiftUI view that I whipped up to demonstrate:

import SwiftUI

struct Person: Decodable {
    let personId: Int
    let name: String
    let firstName: String
    let civility: String
    let fidelityCode: String
    let phoneCode: String
    let phoneNumber: String
    let cniCode: String?
    let email: String
    let vipStatus: Int
    let activationStatus: Int
    let countryCode: Int
    let birthDate: String
    let searchStatus: String
}

enum PersonOrError: Decodable {
    case personVal(Person)
    case errorVal(Int)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let intVal = try? container.decode(Int.self) {
            self = .errorVal(intVal)
            return
        }
        if let personVal = try? container.decode(Person.self) {
            self = .personVal(personVal)
            return
        }
        throw DecodingError.typeMismatch(PersonOrError.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ValueUnion"))
    }
}

struct Value: Decodable {
    let person: PersonOrError
}

struct PEResponse: Decodable {
    let error: String
    let value: Value
}

struct PersonOrErrorView: View {

    let jsonError = {
        return """
{
    "error": "false",
    "value": {
        "person": -1
    }
}
""".data(using: .utf8)!
    }()

    let jsonPerson = {
      return """
{
    "error": "false",
    "value": {
        "person": {
            "personId": 1529853,
            "name": "test",
            "firstName": "tezt",
            "civility": "MR",
            "fidelityCode": "LM57CC",
            "phoneCode": "+237",
            "phoneNumber": "+237",
            "cniCode": null,
            "email": "test6@adwa.cm",
            "vipStatus": 0,
            "activationStatus": 1,
            "countryCode": 30,
            "birthDate": "2002-10-12",
            "searchStatus": "RAS"
        }
    }
}
""".data(using: .utf8)!
    }()

    enum PorE {
        case person, error
    }
    @State private var whichJSON: PorE = .person

    @State private var textDisplay: String = ""

    var body: some View {
        VStack {
            Text(textDisplay)
            Button("Switch") {
                whichJSON = whichJSON == .person ? .error : .person
            }
        }
        .onAppear { loadJSON() }
        .onChange(of: whichJSON) { _ in
            loadJSON()
        }
    }

    func loadJSON() {
        let decoder = JSONDecoder()
        do {
            let response =
                try decoder.decode(PEResponse.self,
                                   from: whichJSON == .person ? jsonPerson : jsonError)
            switch response.value.person {
            case .errorVal(let i): textDisplay = "Error \(i)"
            case .personVal(let p): textDisplay = p.name
            }
        }
        catch {
            textDisplay = "Error!"
        }
    }
}

struct PersonOrErrorView_Previews: PreviewProvider {
    static var previews: some View {
        PersonOrErrorView()
    }
}

Hopefully this makes sense.

3      

I totally forgot after testing, thank you so much 🙏

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.