App developer

Simple JSON Parsing with Codable

As I rewrite Amazing Flag Quiz for iOS 11, one of the greatest things I’ve come across is the new Codable protocol in Swift 4. Before I get into why it’s great, here’s a bit of background: Amazing Flag Quiz v1 to v2.1.2 (current) contains an XML file of ids, country names (short and long, I don’t know why!), continent names, flag image names, and population (I don’t know why!). That file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
    <longCountryName>'c5land Islands</longCountryName>
    <countryContinent>Don't Use</countryContinent>

To use this file meant creating an NSXMLParser and all the code that goes along with it. For version 3 of Amazing Flag Quiz, I’ve decided to convert the XML to JSON and use a Country struct that conforms to Decodable.

The tidied up JSON file looks like this:

  "name": "Afghanistan",
  "game": "Asia",
  "excludeFromWorldChallenge": false,
  "flag": "AF.png"
  "name": "Albania",
  "game": "Europe",
  "excludeFromWorldChallenge": false,
  "flag": "AL.png"

The Country struct mirrors the data set:

/// Representation of data as held in the countryFlags.json file.
struct Country: Decodable {
    var name: String
    var flag: String
    var game: String
    var excludeFromWorldChallenge: Bool

I then have a single function to extract a Country array for the game type the player picks:

func flags(for gameType: GameType?) -> [Country] {
    let decoder = JSONDecoder()
    let data = try? Data(contentsOf: file!)
    let decodedData = try? decoder.decode([Country].self, from: data!)
    guard let countries = decodedData else {
        return []
    if gameType == nil {
        return countries
    if gameType == {
        return GKRandomSource.sharedRandom().arrayByShufflingObjects(in: countries.filter({ $0.excludeFromWorldChallenge == false })) as! [Country]
    return  GKRandomSource.sharedRandom().arrayByShufflingObjects(in: countries.filter({ $ == gameType!.rawValue })) as! [Country]


If a player selected the Asia game type:

let gameArray = flags(for: .asia) // returns a shuffled array of Asian countries.

Codable has made JSON parsing so simple. I’d recommend the Ulimate Guide to JSON Parsing With Swift 4 by Ben Scheirman as further reading.