简体   繁体   中英

Parsing JSON using a Swift Dictionary

I am having a hard time parsing JSON with Swift. I have written a function that make a get request to an api and retrieves the data as JSON and converts it into a dictionary. After that I am trying to use a tableViewController to set each title and subtitle from the values I received from the JSON. I am trying to set the title as the homeTeam and the subtitle as the awayTeam. I do not know much about Swift so I was hoping for some help.

Here is my JSON that is stored in a dictionary:

dictionary = ["scoreboard": {
    gameScore =     (
                {
            game =             {
                ID = 35119;
                awayTeam =                 {
                    Abbreviation = ATL;
                    City = Atlanta;
                    ID = 91;
                    Name = Hawks;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = CLE;
                    City = Cleveland;
                    ID = 86;
                    Name = Cavaliers;
                };
                location = "Quicken Loans Arena";
                time = "7:30PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35120;
                awayTeam =                 {
                    Abbreviation = MIA;
                    City = Miami;
                    ID = 92;
                    Name = Heat;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = TOR;
                    City = Toronto;
                    ID = 81;
                    Name = Raptors;
                };
                location = "Air Canada Centre";
                time = "7:30PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35121;
                awayTeam =                 {
                    Abbreviation = NYK;
                    City = "New York";
                    ID = 83;
                    Name = Knicks;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = MEM;
                    City = Memphis;
                    ID = 107;
                    Name = Grizzlies;
                };
                location = "FedEx Forum";
                time = "8:00PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35122;
                awayTeam =                 {
                    Abbreviation = DET;
                    City = Detroit;
                    ID = 88;
                    Name = Pistons;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = HOU;
                    City = Houston;
                    ID = 109;
                    Name = Rockets;
                };
                location = "Toyota Center";
                time = "8:00PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35123;
                awayTeam =                 {
                    Abbreviation = SAS;
                    City = "San Antonio";
                    ID = 106;
                    Name = Spurs;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = DAL;
                    City = Dallas;
                    ID = 108;
                    Name = Mavericks;
                };
                location = "American Airlines Center";
                time = "8:30PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35124;
                awayTeam =                 {
                    Abbreviation = NOP;
                    City = "New Orleans";
                    ID = 110;
                    Name = Pelicans;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = DEN;
                    City = Denver;
                    ID = 99;
                    Name = Nuggets;
                };
                location = "Pepsi Center";
                time = "9:00PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35125;
                awayTeam =                 {
                    Abbreviation = MIN;
                    City = Minnesota;
                    ID = 100;
                    Name = Timberwolves;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = UTA;
                    City = Utah;
                    ID = 98;
                    Name = Jazz;
                };
                location = "Vivint Smart Home Arena";
                time = "9:00PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35126;
                awayTeam =                 {
                    Abbreviation = OKL;
                    City = "Oklahoma City";
                    ID = 96;
                    Name = Thunder;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = PHX;
                    City = Phoenix;
                    ID = 104;
                    Name = Suns;
                };
                location = "Talking Stick Resort Arena";
                time = "10:00PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        },
                {
            game =             {
                ID = 35127;
                awayTeam =                 {
                    Abbreviation = SAC;
                    City = Sacramento;
                    ID = 103;
                    Name = Kings;
                };
                date = "2017-04-07";
                homeTeam =                 {
                    Abbreviation = LAL;
                    City = "Los Angeles";
                    ID = 105;
                    Name = Lakers;
                };
                location = "Staples Center";
                time = "10:30PM";
            };
            isCompleted = false;
            isInProgress = false;
            isUnplayed = true;
            quarterSummary = "<null>";
        }
    );
    lastUpdatedOn = "<null>";
}]

Here is what I have currently for setting my title and subtitle in Swift:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "NBAScore", for: indexPath)

        // Configure the cell...                
        if let scoreBoard = d.dictionary["scoreboard"] as? [String:AnyObject]
        {
            if let gameScore = scoreBoard["gameScore"] as? [String:AnyObject]
                {
                    if let game = gameScore["game"] as? [String:AnyObject]
                        {
                            if let awayTeam = game["awayTeam"] as? String
                                {
                                    cell.textLabel?.text = awayTeam                             }
                        }
                }
        }
        return cell
    }

Use the below code to get the team name -

if let scoreBoard = d.dictionary["scoreboard"] as? [String:AnyObject]
        {
            if let gameScore = scoreBoard["gameScore"] as? [String:AnyObject]
                {
                    if let game = gameScore["game"] as? [String:AnyObject]
                        {
                            if let awayTeam = game["awayTeam"] as? [String: AnyObject] {
                                  if let teamName = awayTeam["Name"] as? String {
                                      cell.textLabel?.text = teamName 
                                  }                            
                              }
                        }
                }
        }

最好的方法是为所需的属性创建一个Struct添加变量,然后使用for循环从该结构中创建一个数组以解析json数组并将其附加到新创建的数组中,然后可以使用点表示法访问这些属性在cellForRow函数中

For that purpose I would use some library that was build to parse JSON dictionaries to some model objects as it's a good practice. Eg I would recommend Marshal as it's lightweight and easy to use.

You just create a struct or any other Swift structure and then you call Marshal. Later on you use those mapped objects in your tableView dataSource.

Your 'gameScore' object is an array not a dictionary type ([String:AnyObject]). My mistake that i didn't check the json object properly.

First create an array and store all the team name in that array. For Example, I am storing all the awayteam name for now in an array. Check the below code. I didn't run the below source code in my end, Since your json has problem. It's not a valid json data. There is formatting issue. But this below code will work.

let awayTeamArr = NSMutableArray()
if let scoreBoard = d.dictionary["scoreboard"] as? [String:AnyObject] {
    if let gameScore = scoreBoard["gameScore"] as? NSArray {

        for gameScoreObj in gameScore {
            if let gameObj = gameScoreObj as [String: AnyObject] {
                if let game = gameObj["game"] as? [String:AnyObject] {
                    if let awayTeam = game["awayTeam"] as? [String: AnyObject] {
                        if let teamName = awayTeam["Name"] as? String {
                            awayTeam.add(teamName)
                        }
                    }
                }
            }
        }
    }
}

Then in your tableView delegate method for each cell display the object of that specific index of 'awayTeamArr' object. If this answer worked then make the question as completed.

I was able to figure out an answer to my own question. The "gameScore" key of the dictionary was giving me trouble because I was type casting it incorrectly. It was an Array<[String:Any]> not a dictionary.

 func parseJSON(){
            var s = nbaScore()
            var i = 0
            if let scoreBoard = d.dictionary["scoreboard"] as? [String:AnyObject]
            {
            // Could check the lastUpdattedOn date before doing the following:
                if let gameScore = scoreBoard["gameScore"] as? Array<[String:Any]>
                {   //Loop for # of games
                    //while gameScore[i]["game"] as? [String:Any] != nil
                    while i < gameScore.count
                    //for _ in (gameScore[0]["game"] as? [String:Any])!
                    {

                    // An array of dictionaries
                        if let game = gameScore[i]["game"] as? [String:Any]
                            {
                                s.gameTime = (game["time"] as? String)!

                                if let awayTeam = game["awayTeam"] as? [String:Any]
                                {
                                    s.awayTeamCity = (awayTeam["City"] as? String)!
                                    s.awayTeamName = (awayTeam["Name"] as? String)!
                                }
                                if let homeTeam = game["homeTeam"] as? [String:Any]
                                {
                                    s.homeTeamCity = (homeTeam["City"] as? String)!
                                    s.homeTeamName = (homeTeam["Name"] as? String)!
                                }

                            }
                        if let isUnplayed = gameScore[i]["isUnplayed"] as? String
                        {
                            s.isUnplayed = isUnplayed
                        }
                        if let isInProgress = gameScore[i]["isInProgress"] as? String
                        {
                            s.isInProgress = isInProgress
                        }
                        if let isCompleted = gameScore[i]["isCompleted"] as? String
                        {
                            s.isCompleted = isCompleted
                        }
                        if let awayScore = gameScore[i]["awayScore"] as? String
                        {
                            s.awayTeamScore = awayScore
                        }
                        if let homeScore = gameScore[i]["homeScore"] as? String
                        {
                            s.homeTeamScore = homeScore
                        }
                        i += 1
                        scores.append(s)
                        s.clearData()
                        gamesCount += 1
                    }
                }
            }
        }

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