Reputation: 597
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
?
Upvotes: 1
Views: 843
Reputation: 9665
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.
Upvotes: 1