These are the protocols I currently have.
protocol InventoryObject: ObservableObject, Identifiable, CustomStringConvertible, Hashable {
var id: UUID { get }
var name: String { get set }
var description: String { get }
static var objectType: String { get }
func isStorageUnit() -> Bool
func isStorageItem() -> Bool
}
protocol InventoryStorageObject: InventoryObject {
associatedtype typeType: InventoryObject
associatedtype locType: InventoryObject
associatedtype storageType: InventoryStorageObject
init(_ name: String, type: typeType, location: locType?)
var storageType: typeType { get }
var storageLocation: locType? { get }
var description: String { get }
static func newStorageUnit(_ name: String, id: UUID, type: typeType, location: locType?) -> storageType
}
protocol InventoryItemObject: InventoryObject {
associatedtype storageType: InventoryStorageObject
var inventoryStorageUnit: storageType { get }
var addedDate: Date { get }
var checkDate: Date? { get }
var expireDate: Date? { get }
func formateDate(_ : Date) -> String
}
I meant that you might need to turn models ( Book , Song ) into one big class hierarchy.
No, that's what I meant, too. E.g.,
class InventoryObjectModel : InventoryObject {
// ...
}
class BookModel: InventoryObjectModel {
// ....
}
class SongModel: InventoryObjectModel {
// ....
}
class InventoryItemModel: InventoryObjectModel, InventoryItemObject {
// ...
}
class InentoryList<T: InventorObject> {
var objectList = [T]()
// I think I also have var listType: T.Type { return T.self }
// But I don't think it was helpful to me [yet anyway] so I may have tossed out that change.
// ...
}
class InventoryStorageModel: InventoryStorageObject {
var bookInventory = InventoryList<BookModel>()
var songIventory = InventoryList<SongModel>()
var itemInventory = InventoryList<InventoryItemModel>()
// ...
}
My thoughts were that, given that sort of design, I could have a Firebase subclass for InventoryStorageModel, but an entirely different set of classes that still conformed to the protocols. And, again, same for Core Data. With the result being that, at launch time, I could decide whether to instantiate InventoryStorageModel, InventoryStorageModelFirebase, or InventoryStorageModelCoreData, and have everything else Just Work. (With, for example, an extension for the Core Data classes to conform to the correct protocol, that would be wrappers for the CD properties/methods.)
But all of that does depend on me being able to correctly create an object from the UI at some point.
Without generics, using only classes, I can check at runtime to see what the type is. And that would let me have something horrible like
if object.list.itemType == BookModel.self {
// SwiftUI/code to create a book
}
if object.list.itemType == SongModel.self {
// SwiftUI/code to create a song
}
if object.list.itemType == InventoryItemModel.self {
// SwiftUI/code to create an inventory item
}
But with generics, I can't. Not as easily and clearly, anyway, but I'm starting to get a grasp on maybe how.
I apologise for this long post, and hope that it makes sense to anyone else but me.