Get Xcode 5 to Warn About New API Calls

Is there a way for Xcode to warn about new API calls?

After digging through AvailabilityInternal.h, I realized that all available versions above the Deployment target are tagged with the __AVAILABILITY_INTERNAL_WEAK_IMPORT macro.

Therefore, I can generate warnings by redefining that macro:

#import <Availability.h>
#undef __AVAILABILITY_INTERNAL_WEAK_IMPORT
#define __AVAILABILITY_INTERNAL_WEAK_IMPORT \
__attribute__((weak_import,deprecated("API newer than Deployment Target.")))

By placing this code in a project's precompiled header, any use of an API that might cause a crash on the lowest supported iOS version now generates a warning. If you correctly guard the call, you can disable the warning specifically for that call (modified exmaple from Apple's SDK Compatibility Guide):

#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
if ([UIPrintInteractionController class]) {
// Create an instance of the class and use it.
}
#pragma GCC diagnostic warning "-Wdeprecated-declarations"
else {
// Alternate code path to follow when the
// class is not available.
}

Get Xcode 5 to warn about new API calls

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

Get Xcode 5 to warn about new API calls

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

Get xcode 4.5 to warn about new API calls

There is a correct answer inside of the question that you linked too. With some experimentation, I came up with this (from mattjgalloway's answer):

#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

Then repeat for all the versions that make sense (i.e. 4.3 and above for Xcode 4.5). The __IPHONE_OS_VERSION_MIN_REQUIRED macro will check the deployment target.

Get xcode 4.5 to warn about new API calls

There is a correct answer inside of the question that you linked too. With some experimentation, I came up with this (from mattjgalloway's answer):

#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

Then repeat for all the versions that make sense (i.e. 4.3 and above for Xcode 4.5). The __IPHONE_OS_VERSION_MIN_REQUIRED macro will check the deployment target.

iOS Xcode: Warn about methods not in minimum target SDK

After doing some research, reading the Apple Doc about it, and trying a number of things. The solution is downloading an old Xcode DMG from Apple, grab the .pkg file for the same SDK as your deployment target and install it in your version of Xcode. Here's how:

  1. Download older Xcode.dmg from Apple
  2. Open the DMG
  3. In Terminal, go into packages: "cd /Volumes/[DMG]/Packages; open ."
  4. Find the SDK you want, something like iPhoneSDK_4.0.pkg
  5. Install that package, but change the install directory to /Applications/Xcode/Contents/Developer
  6. Restart Xcode if it was open.

Now that you have the same SDK as your deployment target, set your BaseSDK to the same. When you build you'll get warnings about missing methods. Your project may or may not successfully build with an older BaseSDK in a new version of Xcode, but that doesn't matter - you've just found the method calls you need to wrap in a feature check with respondsToSelector:.

How to check if not available methods are used if deployment target base sdk?

  1. best way to do that which i found: compile code with old SDK :) link which can help

  2. I think this question is releated with next

  3. I belive that someday Apple allow to compile project for old SDK by simple defining #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_3_0

  4. upd: I found solution here

4.3 5.0 and 5.1 SDK just fail to compile after trying to redefine this macro



Related Topics



Leave a reply



Submit