Last active
May 26, 2020 12:08
-
-
Save smileyborg/d513754bc1cf41678054 to your computer and use it in GitHub Desktop.
Backwards compatible macros for Objective-C nullability annotations and generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The following preprocessor macros can be used to adopt the new nullability annotations and generics | |
* features available in Xcode 7, while maintaining backwards compatibility with earlier versions of | |
* Xcode that do not support these features. | |
*/ | |
#if __has_feature(nullability) | |
# define __ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN | |
# define __ASSUME_NONNULL_END NS_ASSUME_NONNULL_END | |
# define __NULLABLE nullable | |
#else | |
# define __ASSUME_NONNULL_BEGIN | |
# define __ASSUME_NONNULL_END | |
# define __NULLABLE | |
#endif | |
#if __has_feature(objc_generics) | |
# define __GENERICS(class, ...) class<__VA_ARGS__> | |
# define __GENERICS_TYPE(type) type | |
#else | |
# define __GENERICS(class, ...) class | |
# define __GENERICS_TYPE(type) id | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Here are some examples of the above macros being used. | |
* The comments below each line represent the output of the preprocessor (e.g. what the compiler will see) | |
* when using both Xcode 7 and Xcode 6. | |
*/ | |
#import "Xcode7Macros.h" | |
__ASSUME_NONNULL_BEGIN | |
// Xcode 7: NS_ASSUME_NONNULL_BEGIN | |
// Xcode 6: | |
@interface __GENERICS(MyClass, GenericType1, GenericType2) : NSObject | |
// Xcode 7: @interface MyClass<GenericType1, GenericType2> : NSObject | |
// Xcode 6: @interface MyClass : NSObject | |
@property (nonatomic, strong) __GENERICS(NSArray, __GENERICS(NSDictionary, GenericType1, GenericType2) *) *arrayOfDictionaries; | |
// Xcode 7: @property (nonatomic, strong) NSArray<NSDictionary<GenericType1, GenericType2> *> *arrayOfDictionaries; | |
// Xcode 6: @property (nonatomic, strong) NSArray *arrayOfDictionaries; | |
- (__NULLABLE __GENERICS_TYPE(GenericType2))someMethodWithAParameter:(__NULLABLE NSString *)param; | |
// Xcode 7: - (nullable GenericType2)someMethodWithAParameter:(nullable NSString *)param; | |
// Xcode 6: - (id)someMethodWithAParameter:(NSString *)param; | |
@end | |
__ASSUME_NONNULL_END | |
// Xcode 7: NS_ASSUME_NONNULL_END | |
// Xcode 6: |
@smileyborg I believe the macro breaks bridging into swift?
@samjarman They shouldn't, these are being used by projects that bridge to Swift. Are you seeing a specific issue?
Very cool, do you have a license for your code that we can use?
Thank you.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@colasjojo You can probably just omit (delete) the
_Nullable
and<CKRecord *>
/<CKRecordID *>
entirely and it should continue to compile fine on Xcode 7 with no change in behavior. If you want to preserve the type information then you should try converting the syntax to use the macros in this gist, something like:(You would need to also define a new macro for
_Nullable
and substitute that if you're trying to support Xcode 6.2 and earlier.)