简体   繁体   中英

Why am I getting nil for the Int64 value?

I run this code and get clients names correctly, but when it comes to integers (number of awards, number of cars, number of dogs), it seems that I am not getting anything from the API (the '?? 0' part kicks in and returns nil).

Here's my code:

func getAllClients() {
    AF.request("xxxxxxxxxxxxx", headers: headers).responseJSON {response in
        let result = response.value
        var allCli: [ClientsData] = []
        if result != nil {
            let dataDictionary = result as! [Dictionary <String, AnyObject>]
            for clientsData in dataDictionary {
                let cllstname = clientsData["cllstname"] as? String ?? "Error"
                let noofawards = clientsData["noofawards"] as? Int64 ?? 0
                let noofcars = clientsData["noofcars"] as? Int64 ?? 0
                let noofdogs = clientsData["noofdogs"] as? Int64 ?? 0
                let clientsObject = ClientsData (cllstname: cllstname, noofawards: noofawards, noofcars: noofcars, noofdogs: noofdogs)

                allCli.append(clientsObject)
            }
        }
        self.allClients = allCli.sorted(by: { $0.noofawards > $1.noofawards })
    }
}

However, if I do

print(clientsData)

I get a nice and full response in the debug section. All the numbers are there, so API is sending, and I am receiving.

Why am I getting nil results, and how to fix this?

You should look at the raw JSON. For example, grab the data and

let string = response.data.flatMap { String(data: $0, encoding: .utf8) }
print(string ?? "Unable to get String representation of the data")

I'm wagering that the numbers will be in quotes meaning that they're really string representations of numeric values, not actually numbers:

[{"noofcars": "2", "cllstname": "Smith", ...

Note, I'm asking you to look at the raw JSON, not just the result which has already been decoded. We need to see how the raw JSON represented these numeric values.

Let's assuming for a second that my supposition is correct, that you're getting these values as strings. Clearly, the correct solution is that the web service should send numeric value as numbers, not as strings. But you want to work with the existing JSON, you first get the String representation for numofcars (etc.), and then convert that to an numeric value. For example:

AF.request("xxxxxxxxxxxxx", headers: headers).responseJSON { response in
    guard let dictionaries = response.value as? [[String: Any]] else { return }

    self.allClients = dictionaries.compactMap { dictionary -> ClientsData? in
        let cllstname = dictionary["cllstname"] as? String ?? "Error"
        let awards = (dictionary["noofawards"] as? String).flatMap { Int($0) } ?? 0
        let cars = (dictionary["noofcars"] as? String).flatMap { Int($0) } ?? 0
        let dogs = (dictionary["noofdogs"] as? String).flatMap { Int($0) } ?? 0
        return ClientsData(cllstname: cllstname, noofawards: awards, noofcars: cars, noofdogs: dogs)
    }
    .sorted { $0.noofawards > $1.noofawards }
}

FWIW, please forgive the refactoring above, as I would recommend map or compactMap rather than building an empty array and appending values to it. It's just a bit more concise

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM