SwiftUI: Rendering an Array of Dictionaries in a List

Updated: May 13, 2023 By: Goodman Post a comment

This practical article will walk you through a couple of different ways to render an array of dictionaries in a List in SwiftUI. I assume you already have some basic understanding of SwiftUI, so I won’t waste your time by explaining what it is or rambling about the history of that Apple’s user interface toolkit. It’s better to write some code and make seeable things.

Using a ForEach loop and the subscript syntax (simple)

You can use a ForEach loop to iterate over an array of dictionaries and create a row for each dictionary. You need to make sure each dictionary has a unique identifier or use the .self key path as the id parameter.

The values of a dictionary can be accessed with the subscript syntax. However, they are optional values, thus we need to use the nil-coalescing operator like so:

Text(item["name"] ?? "")

Example screenshot:

The complete code:

//
//  ListExample.swift
//  Examples
//
//  Created by Goodman on 13/05/2023.
//

import SwiftUI

// Assume you have an array of dictionaries like this
let items = [
    ["name": "Item 1", "description": "This is some description of item 1"],
    ["name": "Item 2", "description": "This is some description of item 2"],
    ["name": "Item 3", "description": "This is some description of item 3"],
    ["name": "Item 4", "description": "This is some description of item 4"],
    ["name": "Item 5", "description": "This is some description of item 5"],
]

struct ListExample: View {
    var body: some View {
        // You can use a ForEach loop to render each dictionary in a List
        List {
            ForEach(items, id: \.self) { item in
                VStack (alignment: .leading) {
                    // use the subscript syntax to access the values of each ditionary
                    Text(item["name"] ?? "No name").bold().font(.title)
                    Text((item["description"] ?? "Unknown")).foregroundColor(.gray)
                }
            }
        }
    }
}

struct ListExample_Previews: PreviewProvider {
    static var previews: some View {
        ListExample()
    }
}

See also: Access and Update Values in a Swift Dictionary.

Creating a custom struct for data modeling (recommended)

If you’re working on a serious project, you should model your data with structs (unfortunately, this requires a little extra work).

Example screenshot:

Complete code:

//
//  ListExample.swift
//  Examples
//
//  Created by Goodman on 13/05/2023.
//

import SwiftUI

// An array of dictionaries
let data = [
    ["name": "Wolf", "job": "iOS Developer"],
    ["name": "Demon Warlock", "job": "Backend Developer"],
    ["name": "Tokichiro", "job": "Frontend Developer"],
    ["name": "The Raging Bull", "job": "DevOps Developer"],
    ["name": "Pennywise the Clown", "job": "Android Developer"],
]

// Create a struct that conforms to Decodable and Identifiable
struct Person: Decodable, Identifiable {
    var id = UUID()
    let name: String
    let job: String
}

struct ListExample: View {
    // Convert the data into an array of struct instances
    let people = data.map {Person(name: $0["name"] ?? "Missing", job: $0["job"] ?? "Unknown")}
    
    var body: some View {
        // Implement the List
        List(people) { person in
            HStack {
                Text(person.name).font(.headline).foregroundColor(.blue)
                Text(person.job).font(.subheadline)
            }
        }
    }
}

struct ListExample_Previews: PreviewProvider {
    static var previews: some View {
        ListExample()
    }
}

There is more than one way to turn an array of dictionaries into an array of structs in Swift. In the example above, I used the map() method. However, you can choose another approach if you like.