'Dictionary of custom objects, how best to sort and display in a SwiftUI view using List and ForEach?
I have a customObject which I store in Firebase's realtime database:
struct CustomObject: Codable {
var id: UUID?
var name: String?
var status: String?
}
The customObjects are stored in a Dictionary with UUID being the key:
I am able to load the data into a [String: CustomObject] Dictionary in my iOS application, but I am unsure if my approach to sort and display the customObjects using a List() ForEach(...) { is a best practice.
my current solution is to build an Array when the Dictionary is loaded
I use didSet everytime the database updates to recreate an Array which I can use on the list():
class AppManager: ObservableObject {
@Published var customObjectArray: [CustomObject] = []
@Published var customObjectDictionary: [String:CustomObject]? {
didSet {
if customObjectDictionary != nil {
customObjectArray = []
for (key, value) in customObjectDictionary! {
var tempObject: CustomObject = value
tempObject.id = UUID(uuidString: key)
customObjectArray.append(tempObject)
}
customObjectArraySort()
}
}
}
}
This is my View:
struct MainView: View {
@EnvironmentObject var app: AppManager
var body: some View {
List {
ForEach(app.customObjectArray.indices, id: \.self) { index in
HStack{
Text(app.customObjectArray[index].name ?? "")
Spacer()
Text(app.customObjectArray[index].status ?? "")
}
}
}
}
}
I am aware that a Dictionary is a unordered collection and that attempting to sort based on customObject.name in a list with a Dictionary is unsuitable.
According to Apple's documentation
A dictionary stores associations between keys of the same type and values of the same type in a collection with no defined ordering. Each value is associated with a unique key, which acts as an identifier for that value within the dictionary. Unlike items in an array, items in a dictionary do not have a specified order. You use a dictionary when you need to look up values based on their identifier, in much the same way that a real-world dictionary is used to look up the definition for a particular word.
Is using didSet and making an Array from the Dictionary of customObjects considered a best practice?
Is there a better approach for sorting and listing customObjects from a Dictionary?
Solution 1:[1]
Turning a Dictionary into a RandomAccessCollection, to which an Array conforms, is necessary if your want to run it through a ForEach, so this is fine.
Regardless of whether you have a Dictionary that you convert to an Array as your data source, you shouldn't use .indices in this way, especially for something that is easily made Identifiable.
struct MainView: View {
@EnvironmentObject var app: AppManager
var body: some View {
List {
ForEach(app.customObjectArray) { object in
HStack{
Text(object.name ?? "")
Spacer()
Text(object.status ?? "")
}
}
}
}
}
struct CustomObject: Codable, Identifiable {
var id: UUID // Make this non-optional
var name: String?
var status: String?
}
The way you set it up, if any element is added to, or removed from, the array, you can cause a crash. This means you can't use .onDelete, etc. Also, .onMove won't work properly either.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Yrb |

