Reputation: 8924
I'm trying to "polyfill" NSManagedObjects init(context:) method for below iOS9. Is there a way to do an preprocessor availability check for below iOS10?
Does this even make sense or would there be a linking collision issue b/c we don't know what iOS version a user will be running?
Note this is not the same is the @available(iOS 8, *)
macros. I want the opposite: if NOT available. Or more accurately I want something like @available(iOS <10.0, *)
, "available if iOS is less than 10.0"
Upvotes: 1
Views: 330
Reputation: 138251
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:
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:
.
Upvotes: 1
Reputation: 18591
Try this syntax to show a warning:
@available(iOS, introduced: 8.0, deprecated: 10.0)
Or this one to prevent using it in the current iOS target:
@available(iOS, introduced: 8.0, obsoleted: 10.0)
You may even provide a custom message:
@available(iOS, introduced: 8.0, obsoleted: 10.0, message: "This is obsoleted")
Upvotes: 1
Reputation: 47896
Is this what you are looking for?
@available(iOS, deprecated: 10.0)
Though, it's called Attributes in Swift. No preprocessor.
Upvotes: 0