I read from the header file (UIApplication.h):
typedef NSUInteger UIBackgroundTaskIdentifier;
UIKIT_EXTERN const UIBackgroundTaskIdentifier UIBackgroundTaskInvalid __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0);
It seems that UIBackgroundTaskInvalid is just an ordinary NSUInteger with a given value. Now that I'm writing code that has to be compatible with jailbreaking iOS 3.1.3 (where UIBackgroundTaskInvalid is not defined yet). I might need the real value behind it. Anyone can help?
Thanks in advance.
Di
You can check it with
#if !defined UIBackgroundTaskIdentifier
// Pre iOS 4 Fallback
#endif
The sample above only checks the value on compile time. If you need these kind of checks on run-time you can check this great article.
Related
Consider an app that needs to be compatible with iOS 5 and iOS 6.
Is there a way to mark the code that is there purely for iOS 5 compatibility, so that it appear as a compile error (or warning) when -eventually- the deployment target changes to iOS 6?
Something like this:
#IF_DEPLOYMENT_TARGET_BIGGER_THAN_IOS_5
#OUTPUT_ERROR_MESSAGE
#ENDIF
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
If not, what is the best alternative?
Try this:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
#warning This pre-6.0 code isn't needed anymore
#endif
- (BOOL)shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
This code will cause a compiler warning once the Deployment Target is set to 6.0 or later.
#define MY_CONDITIONAL_DEPRECATED_ATTRIBUTE __deprecated
use it on all methods BUT until you need it turn it quiet
#define MY_CONDITIONAL_DEPRECATED_ATTRIBUTE
Consider looking at how Apple marks that sort of thing in their framework classes. It seems they're making use of the Availability.h and AvailabilityInternal.h classes in the SDK.
I am unable to get clear idea about the following method:
- (BOOL) isPad {
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
Actually for iPad applications this method is used but I don't understand that this method actually does, so if anyone could explain it in detail it would be very helpful for me.
Thanks in advance.
The method simply checks if the UI_USER_INTERFACE_IDIOM macro has been defined.
If it is available, it checks to see whether the macro is equal to UIUserInterfaceIdiomPad. If the comparison is true, it returns YES, otherwise if will return NO.
If the macro has not been defined, it means you are running iOS < 3.2 so it is definitely not an iPad.
For documentation, see http://developer.apple.com/library/ios/documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/macro/UI_USER_INTERFACE_IDIOM
As the name suggests, tells you whether the current device that your app is running on is an iPad or not. Returns YES for iPad 1 & 2, and NO for iPhones and iPods.
The #ifdef is the pre-compiler checking to see if a variable UI_USER_INTERFACE_IDIOM is defined and then if it is defined as UIUserInterfaceIdiomPad. If it is defined as UIUserInterfaceIdiomPad that means it is being compiled for the iPad and returns YES, otherwise it returns NO.
Is there a way to test for the existence of C functions in Objective-C? I'm looking for something like "respondsToSelector," but for C functions.
More specifically, I'm trying to test for the existence of "UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque>, CGFloat scale)" in iOS.
Thanks.
if(&UIGraphicsBeginImageContextWithOptions != NULL)
UIGraphicsBeginImageContextWithOptions();
else NSLog(#"No UIGraphicsBeginImageContextWithOptions function");
Yes, see the documentation on weak linking.
It'll work out to checking if the function pointer is NULL before calling the function.
Since UIGraphicsBeginImageContextWithOptions is only present in iOS 4.0 and later, you can check the iOS target version with the __IPHONE_OS_VERSION_MAX_ALLOWED macro:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
UIGraphicsBeginImageContextWithOptions(...);
#else
// Function not available, fail gracefully
#endif
As my iPhone app can run on both OS 3 and 4, I need a way to safely test for iOS 4 SDK features.
I like to avoid checking the [UIDevice ... systemVersion] string (I wonder why Apple failed to provide a numeric value here for easy testing, as it's available on OS X).
Anyway. The usual clean way to test for SDK features is to check if a class reponds to a selector, like this:
if ([UIApplication instancesRespondToSelector:...
And for C methods, one simply checks if the function pointer is NULL:
if (newFunction != NULL) ...
But my problem is that I need to check if a global variable exists. E.g. this one:
extern NSString *const UIApplicationDidEnterBackgroundNotification __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0);
Any idea how one can test their existence at runtime?
Extracted from the help document "SDK Compatibility guide":
Check the availability of an external (extern) constant or a notification name by explicitly comparing its address—and not the symbol’s bare name—to NULL or nil.
For instance, if you wanted to check for the key UIKeyboardFrameBeginUserInfoKey in a keyboard notification dictionary, which is only available in 3.2 and later, you could write:
if (&UIKeyboardFrameBeginUserInfoKey) {
blah;
} else {
blah;
}
the default method is
UIDevice* device = [UIDevice currentDevice];
BOOL backgroundSupported = NO;
if ([device respondsToSelector:#selector(isMultitaskingSupported)])
backgroundSupported = device.multitaskingSupported;
When the test is passed your "it exists in 4.x" global variable shoudl be available.
By the way - it answers if OS4 is there an if the device supports multitasking.
Manfred
HI all
I want to make one app for iPhone 2.2.* and for version 3.0.
Some method in 2.2* is deprecated in 3.0. ( like UITableViewCell setText and setLabel )
Is there any way to check which firmware version is used on iPhone and to set different method to use
You will need to use pre-processor directives for the conditional compilation such as __IPHONE_3_0 and build two separate executables.
For example:
#ifdef __IPHONE_3_0
// code specific to version 3
#else
// code specific to version 2
#end
If you need to detect the version at run-time you can use [[UIDevice currentDevice] systemVersion]. It returns the string with the current version of the iPhone OS.
As mentioned in the other referenced thread, while you can use pre-processor directives to generate two applications from one code base, you will still need two applications (one for 2.x and one for 3.x)
A compile time directive cannot be used to make a run time decision.
There's more detail in the other thread.
Alternate solution, just check using respondsToSelector. For example-
CGSize expectedLabelSize;
if ([subTitle respondsToSelector:#selector(sizeWithAttributes:)])
{
expectedLabelSize = [subTitle sizeWithAttributes:#{NSFontAttributeName:subTitleLabel.font}];
}else{
expectedLabelSize = [subTitle sizeWithFont:subTitleLabel.font constrainedToSize:subTitleLabel.frame.size lineBreakMode:NSLineBreakByWordWrapping];
}