I'm finding the documentation on the new codegen feature in the Core Data Editor in Xcode 8 a bit sparse.
This is a "in Objective-C, I would...." kind of question.
I'm trying to declare a protocol that has 2 methods:
@property (strong, readonly) NSNumber *serverId;
+ (instancetype)objectWithServerId:(NSNumber*)serverId inContext:(NSManagedObjectContext*)moc;
In Objective-C, I would use mogenerator to declare that the baseclass generated should be "MyBaseClass".
and in that baseclass I can implement that class method once. In the Core Data editor, I just have to make sure my entity has that attribute. In the 'human readable' file, I would declare that it conforms to that protocol, and because it inherits from that baseclass (which is basically abstract), it can call that class method listed above.
I think with strong typing, this may not be possible. I have made it work, but each subclass I create (which uses the Xcode generated Extensions) has to implement this method, whereas I would prefer to write the method once as a generic.
In Swift, I added that attribute to the entity (no parent, therefore it is a subclass from NSManagedObject), and did this:
protocol RemoteObjectProtocol {
var serverId: Int64 {get}
static func object<T: NSManagedObject>(WithServerId serverId: Int64, context: NSManagedObjectContext!) -> T?
}
import CoreData
@objc(TestObject)
class TestObject: NSManagedObject {
}
extension TestObject: RemoteObjectProtocol {
// by nature of it being in the generated core data model, we just need to declare its conformance.
static func object<T: NSManagedObject>(WithServerId serverId: Int64, context: NSManagedObjectContext!) -> T? {
// IF YOU FIND A BETTER WAY TO SOLVE THIS, PLEASE DO!
// I would have loved to use a baseclass RemoteObject: NSManagedObject, where you can just implement this
// Method. But there was no way for it to play nicely with the CoreData Editor
// in addition, the convenience method generated by Xcode .fetchRequest() only seems to work outside of this extension.
// Extensions can't make use of other extensions
// So we create the fetch request 'by hand'
let fetchRequest = NSFetchRequest<TestObject>(entityName: "TestObject")
fetchRequest.predicate = NSPredicate(format: "serverId == %i", serverId)
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "serverId", ascending: true)]
fetchRequest.fetchLimit = 1
do {
let fetchedObjects = try context.fetch(fetchRequest)
return fetchedObjects.first as! T?
} catch {
log.warning("Failed to fetch object with serverId:\(serverId) error:\(error)")
}
return nil
}
}