Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does objective-c not have API availability checking?

Swift 2 have API availability checking.

The compiler will give you an error when using an API too new for your minimum target OS

Why can't the objective-c compiler do the equivalent?

I googled objective c API availability checking and only swift 2 results came out so I assume the compiler for objective c can't do that.

like image 358
okysabeni Avatar asked Dec 01 '15 05:12

okysabeni


People also ask

How can I use available in Objective C?

Use the @available() keyword to check availability information in a conditional statement in Objective-C: if (@available(iOS 11, *)) { // Use iOS 11 APIs. } else { // Alternative code for earlier versions of iOS. }

What is API Objective C?

The Objective-C Runtime module APIs define the base of the Objective-C language. These APIs include: Types such as the NSObject class and the NSObjectProtocol protocol that provide the root functionality of most Objective-C classes.

What is the latest version of Objective C?

The latest version of objective C is 2.0.


2 Answers

Xcode 9.0 brings the runtime availability checking syntax from Swift to Objective-C:

if (@available(macOS 10.9, *))
{
// call 10.9+ API
}
else
{
// fallback code
}

this comes complete with warnings for calling APIs that are newer than your deployment target (if those calls are not wrapped in checks).

finally ;)

like image 114
user1259710 Avatar answered Dec 10 '22 05:12

user1259710


The warning (Swift makes it an error) just hadn't been implemented in the Clang compiler for years, but it's not an inherent Objective-C limitation (although due to its dynamic nature, you won't be able to catch all cases), nor Swift terminology.

The Apple macros (e.g., NS_CLASS_AVAILABLE) and source attributes (__attribute__((visibility(...))), __attribute__((availability(...)))) to annotate headers with availability information have been there for years, and they are widely-used in Apple's SDKs. The macros are defined in Foundation's NSObjCRuntime.h, and the Availability.h/AvailabilityMacros.h system headers, and the compiler can (and does) read them.

In early 2015, the -Wpartial-availability warning has been added to Clang's master branch, but this commit/warning hadn't made its way into Apple's version of Clang until (including) Xcode 7.2. You will get an unknown warning option log when adding the warning flag to a project in Xcode 7.2, but the flag is available in Xcode 7.3. There's currently no predefined setting for it, but you can add the flag to Other Warning Flags under Build Settings.

There are other tools that use LLVM libraries to detect partially available APIs, e.g., Deploymate. For my diploma thesis, I developed a tool that integrates directly into Xcode and is based on a modification to the Clang compiler. The code is still online, but I haven't kept up with the general Clang development so it won't be of much use, except for learning purposes. However, the "official" code (linked above) is much cleaner and better.

Edit: Starting with Xcode 9, availability checking will work for Objective-C (and C), too. Instead of using the above-mentioned warning flag, which does not support raising the deployment target temporarily/locally and therefore causes plenty of false positives, there's -Wunguarded-availability, and if (@available(iOS 11, *)) {...} to check and raise the deployment target for the following block of code. It is off by default, but -Wunguarded-availability-new will be on by default, and starts checking anything beyond iOS/tvOS 11, watchOS 4, and High Sierra. More details on that can be found in the Xcode 9 beta release notes, which currently requires signing in with a developer account.

like image 35
hagi Avatar answered Dec 10 '22 04:12

hagi