-
-
Save smileyborg/d513754bc1cf41678054 to your computer and use it in GitHub Desktop.
/** | |
* 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 |
/** | |
* 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: |
Using __apple_build_version__
for the check? What do you think?
// http://en.wikipedia.org/wiki/Xcode#Toolchain_Versions
if defined(__apple_build_version__)
if __apple_build_version__ >= 700059
@ricardopereira I'm not sure what you're asking here.
I want to support NSArray *authParams
and NSArray<NSURLQueryItem *> *authParams
. Any thoughts? /cc @bdash @mickeyreiss
@ricardopereira and why doesn't this work for you?
__GENERICS(NSArray, NSURLQueryItem *) *authParams;
Oh, sorry. Didn't know.
Thanks.
Xcode inserts automatically code such as
saveOperation.modifyRecordsCompletionBlock =
^(NSArray <CKRecord *> * _Nullable savedRecords,
NSArray <CKRecordID *> * _Nullable deletedRecordIDs,
NSError * _Nullable operationErro) {...};
which fails at being compiled with Xcode 6, because of NSArray <CKRecord *> *
. Is it possible to help Xcode 6 compiling?
@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:
saveOperation.modifyRecordsCompletionBlock =
^(__GENERICS(NSArray, CKRecord *) * _Nullable savedRecords,
__GENERICS(NSArray, CKRecordID *) * _Nullable deletedRecordIDs,
NSError * _Nullable operationErro) {...};
(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.)
@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.
What about value type definitions for
NSArray
or key value types forNSDictionary
that are only available for Xcode 7? Do you have any idea?e.g.: