I don't think that this is possible just relying on compile-time operations in Swift. If you care, by writing an extension in Objective-C that defines the method, your implementation will override the platform's when it exists, so that may be a viable and simple solution.
If you only want your implementation to kick in only if there is no native one, you should be able to do that somewhat easily in Objective-C, too. First, I have two warnings:
- You are modifying CoreData, which itself is already quite dynamic, and I'm not sure how it will react.
- I can't verify any of what I'm saying on this computer, so comment if it doesn't work :)
In your bridging header, ensure that the compiler knows that init(context:)
is available regardless of the iOS version:
@interface NSManagedObject ()
+(void)initialize;
-(instancetype)initWithContext:(NSManagedObjectContext* _Nonnull)ctx;
@end
+initialize
methods declared in categories are executed independently of whether the class has a +initialize
method itself or if any other category has one.
The implementation will then look like this:
@implementation NSManagedObject ()
static id initWithContext(NSManagedObject* self, SEL sel, NSManagedObjectContext* context) {
// your implementation goes here
}
+(void)initialize {
SEL init = @selector(initWithContext:);
if (![self instancesRespondToSelector:init]) {
class_addMethod(self, init, (IMP)initWithContext, "@:@");
}
}
@end
Which is rather straightforward in my opinion: check if NSManagedObject
supports initWithContext:
, and if not, add your own implementation of it. You don't need to provide an explicit implementation of initWithContext:
.