Joby Ingram-Dodd
Joby Ingram-Dodd

Reputation: 730

Get JSON Element in Swift 3

Please excuse me if this is a simple question, but I am stuck. I have tried to read everything I can to work it out myself.

I am trying to extract a URL from JSON data, I get the JSON data fine and I can print it to the console, however I can't work out how to access the URL for the audio file.

This is the code I use to get the JSON:

 let session = URLSession.shared
    _ = session.dataTask(with: request, completionHandler: { data, response, error in
        if let response = response,
            let data = data,
            let jsonData = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) {

            if let dictionary = jsonData as? [String: Any] {
                if let prounce = dictionary["pronunciations"] as? [String: Any]{
                    if let audioPath = prounce["audioFile"] as? String {
                        print(audioPath)
                    }

                }
            }

            print(response)
            print(jsonData)
        } else {
            print(error)
            print(NSString.init(data: data!, encoding: String.Encoding.utf8.rawValue))
        }
    }).resume()

The output I get is:

metadata =     {
    provider = "Oxford University Press";
};
results =     (
            {
        id = maladroit;
        language = en;
        lexicalEntries =             (
                            {
                entries =                     (
                                            {
                        etymologies =                             (
                            "late 17th century: French"
                        );
                        grammaticalFeatures =                             (
                                                            {
                                text = Positive;
                                type = Degree;
                            }
                        );
                        senses =                             (
                                                            {
                                definitions =                                     (
                                    "inefficient or inept; clumsy:"
                                );
                                examples =                                     (
                                                                            {
                                        text = "both men are unhappy about the maladroit way the matter has been handled";
                                    }
                                );
                                id = "m_en_gb0494140.001";
                            }
                        );
                    }
                );
                language = en;
                lexicalCategory = Adjective;
                pronunciations =                     (
                                            {
                        audioFile = "http://audio.oxforddictionaries.com/en/mp3/maladroit_gb_1.mp3";
                        dialects =                             (
                            "British English"
                        );
                        phoneticNotation = IPA;
                        phoneticSpelling = "\U02ccmal\U0259\U02c8dr\U0254\U026at";
                    }
                );
                text = maladroit;
            }
        );
        type = headword;
        word = maladroit;
    }
);

}

I want to get the URL called audioFile in the pronunciations. Any help is much appreciated.

Upvotes: 2

Views: 1189

Answers (1)

OOPer
OOPer

Reputation: 47896

If my guess is right, your output shown above lacks opening brace { at the top of the output.

(I'm also assuming the output is taken from your print(jsonData).)

Your jsonData is a Dictionary containing two values:

  • A dictionary value for "metadata"
  • An array value for "results"

So, you cannot retrieve a value for "pronunciations" directly from jsonData (or dictionary).

You may need to:

  • Retrieve the value for "results" from jsonData, it's an Array
  • Choose one element from the "results", it's a Dictionary
  • Retrieve the value for "lexicalEntries" from the result, it's an Array
  • Choose one element from the "lexicalEntries", it's a Dictionary
  • Retrieve the value for "pronunciations" from the lexicalEntry, it's an Array
  • Choose one element from the "pronunciations", it's a Dictionary

Here, you can access the values in each pronunciation Dictionary. In code, you need to do something like this:

if
    let dictionary = jsonData as? [String: Any],
    let results = dictionary["results"] as? [[String: Any]],
    //You need to choose one from "results"
    !results.isEmpty, case let result = results[0],
    let lexicalEntries = result["lexicalEntries"] as? [[String: Any]],
    //You need to choose one from "lexicalEntries"
    !lexicalEntries.isEmpty, case let lexicalEntry = lexicalEntries[0],
    let pronunciations = lexicalEntry["pronunciations"] as? [[String: Any]],
    //You need to choose one from "lexicalEntries"
    !pronunciations.isEmpty, case let pronunciation = pronunciations[0]
{
    //Here you can use `pronunciation` as a Dictionary containing "audioFile" and some others...
    if let audioPath = pronunciation["audioFile"] as? String {
        print(audioPath)
    }
}

(You can use let result = results.first instead of !results.isEmpty, case let result = results[0], if you always use the first element for arrays. Other two lines starting from !...isEmpty, case let... as well.)

You need to dig into the target element from the outermost element step by step.

Upvotes: 2

Related Questions