Mostafa Hendawi
Mostafa Hendawi

Reputation: 76

The data returned from the api is always nil?

I'm retrieving data from an API. The problem is the data always returns as nil. It is a list of questions, usually 10. The code I wrote always returns 10 nil results. I tried the same code with different APIs with the same structure and it always works.

This is the struct:

struct Questions: Codable{
    let question: String?
}

This is the code:

guard let url = URL(string: "http://adminsapi.somee.com/Api/Test/?id=1") else { return }
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else { return }
        do{
            let test = try? JSONDecoder().decode([Questions].self, from: data)
            for ask in test{
                print(ask.question)
            }
        }
    }.resume()

This is the result I get:

nil nil nil nil nil nil nil nil nil nil

This is the data returned from the API in postman:

[
    {
        "AskName": "Urgenct of defecation"
    },
    {
        "AskName": "Mucous and streaked stools"
    },
    {
        "AskName": "vomiting"
    },
    {
        "AskName": "Fever"
    },
    {
        "AskName": "Tympany on percussion"
    },
    {
        "AskName": "Bowel sounds"
    },
    {
        "AskName": "shifting dullness"
    },
    {
        "AskName": "psoas and obturator sign"
    },
    {
        "AskName": "rebound tenderness"
    },
    {
        "AskName": "signs of shock"
    }
]

Also, when I try to parse the json and read the whole data in one string, it works completely fine. I don't know where the problem is.

Upvotes: 1

Views: 538

Answers (2)

David S.
David S.

Reputation: 6705

Edited. Your Question struct is incorrect. Here's working playground code that correctly parses the results.

import UIKit
import PlaygroundSupport

let data = """
[
    {
        "AskName": "Urgenct of defecation"
    },
    {
        "AskName": "Mucous and streaked stools"
    },
    {
        "AskName": "vomiting"
    },
    {
        "AskName": "Fever"
    },
    {
        "AskName": "Tympany on percussion"
    },
    {
        "AskName": "Bowel sounds"
    },
    {
        "AskName": "shifting dullness"
    },
    {
        "AskName": "psoas and obturator sign"
    },
    {
        "AskName": "rebound tenderness"
    },
    {
        "AskName": "signs of shock"
    }
]
""".data(using: .utf8)!

struct Questions: Codable{
    let AskName:String
}

do {
    try JSONDecoder().decode([Questions].self, from: data)
} catch {
    print(error)
}

You could also define it as:

struct Questions: Codable {
    let question: String

    private enum CodingKeys: String, CodingKey {
        case question = "AskName"
    }
}

Upvotes: 0

David Pasztor
David Pasztor

Reputation: 54706

Your Question implementation is wrong. You need to tell the compiler that the question variable needs to be decoded using the AskName key.

struct Questions: Codable {
    let question: String?

    private enum CodingKeys: String, CodingKey {
        case question = "AskName"
    }
}

Upvotes: 1

Related Questions