Reputation: 10938
There was a method for Xcode 4.x:
#define __AVAILABILITY_TOO_NEW __attribute__((deprecated("TOO NEW!"))) __attribute__((weak_import))
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
#undef __AVAILABILITY_INTERNAL__IPHONE_6_0
#define __AVAILABILITY_INTERNAL__IPHONE_6_0 __AVAILABILITY_TOO_NEW
#endif
But that doesn't work anymore because the iOS 7 SDK Availability macros have changed and now have more variances and options:
iOS 6 SDK's AvailabilityInternal.h:
#define __AVAILABILITY_INTERNAL__IPHONE_6_0 __attribute__((availability(ios,introduced=6.0)))
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_0 __attribute__((availability(ios,introduced=6.0,deprecated=6.0)))
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_1 __attribute__((availability(ios,introduced=6.0,deprecated=6.1)))
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_NA __attribute__((availability(ios,introduced=6.0)))
iOS 7 SDK:
#define __AVAILABILITY_INTERNAL__IPHONE_6_0 __attribute__((availability(ios,introduced=6.0)))
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_0 __attribute__((availability(ios,introduced=6.0,deprecated=6.0)))
#if __has_feature(attribute_availability_with_message)
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_0_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=6.0,message=_msg)))
#else
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_0_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=6.0)))
#endif
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_1 __attribute__((availability(ios,introduced=6.0,deprecated=6.1)))
#if __has_feature(attribute_availability_with_message)
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_1_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=6.1,message=_msg)))
#else
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_6_1_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=6.1)))
#endif
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_7_0 __attribute__((availability(ios,introduced=6.0,deprecated=7.0)))
#if __has_feature(attribute_availability_with_message)
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_7_0_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=7.0,message=_msg)))
#else
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_7_0_MSG(_msg) __attribute__((availability(ios,introduced=6.0,deprecated=7.0)))
#endif
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_NA __attribute__((availability(ios,introduced=6.0)))
#define __AVAILABILITY_INTERNAL__IPHONE_6_0_DEP__IPHONE_NA_MSG(_msg) __attribute__((availability(ios,introduced=6.0)))
Could it be that Xcode 5 has the attribute_availability_with_message
feature so the old macro redefinition is no longer used?
Also it would be cool to print more than the "TOO NEW!" message with all the new introduced/deprecated information.
Edit:
Most definitions in iOS 7 SDK moved from __OSX_AVAILABLE_STARTING(_ios)
/__AVAILABILITY_INTERNAL##_ios
to NS_AVAILABLE_IOS(_ios)
/CF_AVAILABLE_IOS(_ios)
, so redefining:
#undef NS_AVAILABLE_IOS
#define NS_AVAILABLE_IOS(_ios) __attribute__((availability(ios,__NSi_##_ios))) __attribute__((deprecated("TOO NEW!")))
Should work. And actually it does because Xcode 5 autocompletion shows the methods as deprecated.
Building however doesn't trigger any warning despite having the GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS
build option on...
Upvotes: 1
Views: 3122
Reputation: 33421
I found some other information on the topic. This will redefine a different macro (NS_AVAILABLE_IOS
). Perhaps it will work a bit better than
(Source https://www.albertopasca.it/whiletrue/xcode-warn-about-new-api-classes-and-methods/)
#import <availability.h>
#import <foundation/NSObjCRuntime.h>
#if( 1 )
#define APICHECK_2_0( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_2_1( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_2_2( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_3_0( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_3_1( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_3_2( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_4_0( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_4_1( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_4_2( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_4_3( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_5_0( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#define APICHECK_5_1( _ios ) __attribute__((deprecated("UNAVAILABLE PRIOR TO 5.1")))
#define APICHECK_6_0( _ios ) __attribute__((deprecated("UNAVAILABLE PRIOR TO 6.0")))
#define APICHECK_6_1( _ios ) __attribute__((deprecated("UNAVAILABLE PRIOR TO 6.1")))
#define APICHECK_NA( _ios ) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
#undef NS_AVAILABLE_IOS
#define NS_AVAILABLE_IOS(_ios) APICHECK_ ## _ios( _ios )
#undef NS_AVAILABLE
#define NS_AVAILABLE(_mac, _ios) APICHECK_ ## _ios( _ios )
#endif
You can use conditionals the same way as before (#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
etc). Note that I have not tested this because I don't have Xcode 5 on my machine yet. If you want to turn the warnings into errors you can use __attribute__((unavailable("UNAVAILABLE PRIOR TO 6.1")))
etc.
You can also try using this program, though it is paid. http://www.deploymateapp.com/
Upvotes: 1
Reputation: 10938
As of Xcode 5.0 it is not possible to get warnings from new API calls by redefining macros.
Redefining a macro does show up in autocompletion and preprocessed preview (Assistant Editor > Preprocess) but does not trigger a warning despite using deprecate
or unavailable
keywords.
Xcode 5.0.1+ does show a warning so both __AVAILABILITY_INTERNAL__IPHONE_X_X
and NS_AVAILABLE_IOS
can now be redefined as mentioned in the question and @borrrden answer.
Code available as a Gist and as a library:
#define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_5_0
#ifndef __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED
#define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_OS_VERSION_MIN_REQUIRED
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_OS_VERSION_MIN_REQUIRED
#error You cannot ask for a soft max version which is less than the deployment target
#endif
#define __NBU_AVAILABILITY_STARTING(version) __attribute__((deprecated("Only available in iOS " version "+"))) __attribute__((weak_import))
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_2_0
#undef __AVAILABILITY_INTERNAL__IPHONE_2_0
#define __AVAILABILITY_INTERNAL__IPHONE_2_0 __NBU_AVAILABILITY_STARTING("2.0")
#define __NBU_APICHECK_2_0(_ios) __NBU_AVAILABILITY_STARTING("2.0")
#else
#define __NBU_APICHECK_2_0(_ios) CF_AVAILABLE_IOS(_ios)
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_2_1
#undef __AVAILABILITY_INTERNAL__IPHONE_2_1
#define __AVAILABILITY_INTERNAL__IPHONE_2_1 __NBU_AVAILABILITY_STARTING("2.1")
#define __NBU_APICHECK_2_1(_ios) __NBU_AVAILABILITY_STARTING("2.1")
#else
#define __NBU_APICHECK_2_1(_ios) CF_AVAILABLE_IOS(_ios)
#endif
//...
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_7_0
#undef __AVAILABILITY_INTERNAL__IPHONE_7_0
#define __AVAILABILITY_INTERNAL__IPHONE_7_0 __NBU_AVAILABILITY_STARTING("7.0")
#define __NBU_APICHECK_7_0(_ios) __NBU_AVAILABILITY_STARTING("7.0")
#else
#define __NBU_APICHECK_7_0(_ios) CF_AVAILABLE_IOS(_ios)
#endif
#undef NS_AVAILABLE_IOS
#define NS_AVAILABLE_IOS(_ios) __NBU_APICHECK_##_ios( _ios )
#undef __OSX_AVAILABLE_BUT_DEPRECATED
#define __OSX_AVAILABLE_BUT_DEPRECATED(_osx, _osxDep, _ios, _iosDep) __AVAILABILITY_INTERNAL##_ios
#undef __OSX_AVAILABLE_BUT_DEPRECATED_MSG
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osx, _osxDep, _ios, _iosDep, _msg) __AVAILABILITY_INTERNAL##_ios
Upvotes: 0
Reputation: 10466
Use the method described here: https://stackoverflow.com/a/8919108/480467
In addition, to get this to work under XCode 5 you need to also redefine the NS_AVAILABLE and NS_DEPRECATED macros because CFAvailability.h distinguishes between compilers that support the attribute_availability_with_message feature.
See my response here: https://stackoverflow.com/a/19704587/480467
Upvotes: 0
Reputation: 8513
In Xcode 5, you should be able to use/adapt the code from my answer to https://stackoverflow.com/a/19567669/473067. It could be incompatible with the use of modules, though, I haven't checked.
I posted a summary here: http://iphone.m20.nl/wp/2013/10/xcode-5-and-flagging-weak-linked-unavailable-symbols-from-a-newer-sdk/
Upvotes: 0