I'm currently playing with Core Data, SwiftUI and the new Sidebar. What I do is that I create a group for every entity of Core Data and the subentries for every group are the actual records in each entity. While the part of SwiftUI with sidebar is working well I'm now struggling to add more functionality to it.
This is the code I use for creating my sidebar:
/**
Each case represents a Category header in the submenu. Cases are case sensitive, for reach entity of Core Data you want to have as a Category header in the sidebar you have to add a case. Each Entity class as to implement the MenuItemObject Protocol
*/
enum MenuEntity: String, CaseIterable {
case Patient
case Contact
case Medicament
case Exercise
/**
Creates the sidebar menu
- parameters: context: A valid NSManegedObjectContext
- returns: MenuItems with Header and Menu Entries
*/
public static func createMenu(_ context: NSManagedObjectContext) -> [MenuItem] {
var items = [MenuItem]()
for entity in MenuEntity.allCases {
var item = MenuItem(id: UUID(), entryName: entity.rawValue, entryType: entity.rawValue)
if let e = Bundle.main.classNamed(entity.rawValue) as? MenuItemObject.Type {
item.menuItems = e.generateMenuItems(context)
}
items.append(item)
}
return items
}
}
/**
Core Data entity which should be shown in the Sidebar must implement this protocol
*/
protocol MenuItemObject where Self: NSManagedObject {
var id: UUID { get set }
static func generateMenuItems(_ context: NSManagedObjectContext) -> [MenuItem]
}
/**
MenuItem for the sidabar
*/
struct MenuItem: Identifiable {
var id: UUID
var entryName: String
var entryType: String
var menuItems: [MenuItem]?
}
No I want to add the possiblity that when I click on a entry a form is opened and I can edit this entry. Therefore, I need to fetch the actual entry from the database. So I made an addition to the protocol.
protocol MenuItemObject where Self: NSManagedObject {
associatedtype ThisType
var id: UUID { get set }
static func generateMenuItems(_ context: NSManagedObjectContext) -> [MenuItem]
static func getObjectFor(_ uuid: UUID, in context: NSManagedObjectContext) -> ThisType?
}
But now I get the error in the function createMenu "Protocol 'MenuItemObject' can only be used as a generic constraint because it has Self or associated type requirements" and I haven't found an option to get it working again. Could you give me a hint what I'm doing wrong and how to fix it. Perhaps if someone is able to explain me what Swift does behind the scenes and why my addition breaks the working code?
Thank you,
Gerd