Do exist some standard defines, that specify destination platform, e.g. DEST_IOS or DEST_OSX? Or must I add its in project's settings?
I need this for using same library on Mac and iPad.
Yes. Include TargetConditionals.h, and I use the following to make them a bit easier to use:
#import <TargetConditionals.h>
#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
#define TARGET_OSX 1
#else
#define TARGET_IOS 1
#endif
(this is in a common project header file).
And then to use the macros:
#if TARGET_OSX
// OSX-specific thing here
#else
// iOS-specific thing here
#endif
Related
I try to define a macro like this:
#import <CoreFoundation/CFBase.h>
#if __LLP64__
#define CFIndexMax LONG_LONG_MAX;
#define CFIndexMin LONG_LONG_MIN;
#else
#define CFIndexMax LONG_MAX;
#define CFIndexMin LONG_MIN;
#endif
But Xcode always warn me has no define of __LLP64_ which is conditional defined in CFBase.h.
Your problem is that you are checking the value of __LLP64__ but you want to check for the existence of __LLP64__:
#ifdef __LLP64__
#define CFIndexMax LONG_LONG_MAX
#define CFIndexMin LONG_LONG_MIN
#else
#define CFIndexMax LONG_MAX
#define CFIndexMin LONG_MIN
#endif
However, only Windows uses the LLP64 model. Are you planning to build this code on Windows? If not, you should simplify your code by eliminating the conditional.
Actually, the compiler defines __LLP64__ (or more likely __LP64__).
If you take a look at the CFBase.h pre-processor logic again, you'll see it forcibly defines __LLP64__ when compiling for a 64-bit Windows target:
#if defined(__WIN64__) && !defined(__LLP64__)
#define __LLP64__ 1
#endif
Copyright (c) 1998-20016 Apple Inc.
If you're concerned about the size of CGFloat (or even CFIndex types on macOS, take a look at CGBase.h to see how things are defined:
#if defined(__LP64__) && __LP64__
#define CGFLOAT_TYPE double
#define CGFLOAT_IS_DOUBLE 1
#define CGFLOAT_MIN DBL_MIN
#define CGFLOAT_MAX DBL_MAX
#else
#define CGFLOAT_TYPE float
#define CGFLOAT_IS_DOUBLE 0
#define CGFLOAT_MIN FLT_MIN
#define CGFLOAT_MAX FLT_MAX
#endif
Copyright (c) 2000-2011 Apple Inc.
You can conditionally define your max and min CFIndexes based on the boolean value of CGFLOAT_IS_DOUBLE, which is not changing any time soon.
Lastly, I believe Windows is the only OS whose size of long types are 32 bits in a 64-bit runtime (that is, compared to linux and macOS which are 64 bits in a 64-bit runtime).
If you're sure you're switching on the right define, always check if the variable be defined first in the pre-compiler:
#if defined(__LLP64__) & __LLP64__
// conditionally define more stuff
#endif
My project contains 3 targets and it requires some credential details specific to target. I have defines.h file where I am checking the current target and then initialising constants.
#ifdef XYZ44DEV
#define COM_CMS_URL #"http://xyz.portal.com"
#define COM_CMS_USER #"test"
#define COM_CMS_PASS #"test"
#elif XYZ44UAT
#define COM_CMS_URL #"http://xyz.uat.portal.com"
#define COM_CMS_USER #"uat"
#define COM_CMS_PASS #"uat"
#else
#define COM_CMS_URL #"http://xyz.prod.portal.com"
#define COM_CMS_USER #"Prod"
#define COM_CMS_PASS #"Prod"
#endif
Any target I run, it goes to else case and takes COM_CMS_USER & COM_CMS_PASS as "Prod". Please let me know, what i am missing here.
You need to add preprocessor Macros in build settings as illustrated in image
the output for
NSLog(#"%#",COM_CMS_USER);
is
2016-05-20 11:58:05.315 CustomKeyboard[2952:687530] test
You have to set preprocessing macro in build setting
image 1 : You have to add macro for each your target
image 2 : For macro , you can set only supported versions
What is the purpose of using #define to define a constant with no value?
Such as:
#define TOKEN
You can use it to enable or disable certain code using #ifdef or #ifndef, eg this:
#ifdef TOKEN
printf("token is defined");
#endif
One use for this would be to toggle logging in debug builds. Another would be include guards.
As #Nutomic says, this sort of #define is useful for enabling/disabling certain bits of code. I've seen this used to create compile-time options for a given library:
#ifdef STRICT_PARSING
//...
#endif
#ifdef APPROXIMATE_PARSING
//...
#endif
#ifdef UNICODE //this is especially useful when trying to control Unicode vs ANSI builds
//call Unicode functions here
#else
//call Ansi functions here
#endif
#ifdef USE_STL //another good one, used to activate or deactivate STL-based bits of an API; the function declarations were dependent on USE_STL being defined. A plain-C API was exposed either way, but the STL support was nice too.
std::string MyApi();
#endif
I compiled my app with sdk 6.1 and set the deployment target to iOS 4.3. Does this mean that my app can run on 4.3? I don't have such device and can't actually test it but I would like to know if the app would work on 4.3.
Setting the deployment target to iOS 4.3 ensures your app supports iOS 4.3 and above unless you are not using any features that only supports in higher versions like ARC, Storyboard, autolayout. It is better to test on a device or simulator. You can download the iOS4.3 simulator through Xcode
Xcode-> preferances -> downloads -> iOS 4.3 simulator
if you feel that the class which you have used might not be available in the other ios version then you can check the same using
Using the NSClassFromString function. Pass the name of your class to this method as a string.
If the return value of this function is nil, that class is not available on the device that runs your app;
otherwise, that class is available on the device and you can go ahead and use it as you wish.
Here is an example:
i am checking for NSJSONSerialization class, similarly you can check for your class also,
if (NSClassFromString(#"NSJSONSerialization") != nil) {
/* You can use this class */
[NSJSONSerialization JSONObjectWithData:... /* Put data here */
options:... /* Put options here */
error:...]; /* Handle errors here */
} else {
/* That class is not available */
}
You can run on any device whose iOS version is greater then or equal to the deployment target set by you.
So keep in mind you have not used any framework or features that are not supported in that version.
Hope it helps you.
You can always test your app on 4.3 simulator. Select the iPhone 4.3 Simulator under the "Scheme" menu (you can find it on the right side of the "Run" "Stop" button on top of Xcode). If you cant find the option for 4.3 simulator then you need to download it by going to Xcode->Preference->Downloads->Components->iOS 4.3 Simulator
Sometimes the xcode will not complain about the usage of new features (like autolayout, etc) available in 6.1 but will crash the app when run on 4.3.
test in this way is a solution that works pretty well, but it is not 100% guaranteed
/**
* Example usage:
* If you want to see if you're using methods that are only defined in iOS 4.0 and lower
* then you would use the following. Replace the __IPHONE_4_0 with whatever other macro
* you require. See Availability.h for iOS versions these relate to.
*
* YourProjectPrefixHeader.pch:
* #define __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED __IPHONE_4_0
* #import "ThisFile.h"
*
* // The rest of your prefix header as normal
* #import <UIKit/UIKit.h>
*/
#import <Availability.h>
#define __AVAILABILITY_TOO_NEW __attribute__((deprecated("TOO NEW!")))
#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
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_2_0
#undef __AVAILABILITY_INTERNAL__IPHONE_2_0
#define __AVAILABILITY_INTERNAL__IPHONE_2_0 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_2_1
#undef __AVAILABILITY_INTERNAL__IPHONE_2_1
#define __AVAILABILITY_INTERNAL__IPHONE_2_1 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_2_2
#undef __AVAILABILITY_INTERNAL__IPHONE_2_2
#define __AVAILABILITY_INTERNAL__IPHONE_2_2 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_3_0
#undef __AVAILABILITY_INTERNAL__IPHONE_3_0
#define __AVAILABILITY_INTERNAL__IPHONE_3_0 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_3_1
#undef __AVAILABILITY_INTERNAL__IPHONE_3_1
#define __AVAILABILITY_INTERNAL__IPHONE_3_1 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_3_2
#undef __AVAILABILITY_INTERNAL__IPHONE_3_2
#define __AVAILABILITY_INTERNAL__IPHONE_3_2 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_4_0
#undef __AVAILABILITY_INTERNAL__IPHONE_4_0
#define __AVAILABILITY_INTERNAL__IPHONE_4_0 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_4_1
#undef __AVAILABILITY_INTERNAL__IPHONE_4_1
#define __AVAILABILITY_INTERNAL__IPHONE_4_1 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_4_2
#undef __AVAILABILITY_INTERNAL__IPHONE_4_2
#define __AVAILABILITY_INTERNAL__IPHONE_4_2 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_4_3
#undef __AVAILABILITY_INTERNAL__IPHONE_4_3
#define __AVAILABILITY_INTERNAL__IPHONE_4_3 __AVAILABILITY_TOO_NEW
#endif
#if __IPHONE_OS_VERSION_SOFT_MAX_REQUIRED < __IPHONE_5_0
#undef __AVAILABILITY_INTERNAL__IPHONE_5_0
#define __AVAILABILITY_INTERNAL__IPHONE_5_0 __AVAILABILITY_TOO_NEW
#endif
I would like to do something similar to #ifdef __linux__, but with the bada SDK. Is there a constant defined by default?
Also, can I detect when I am compiling for the simulator?
You can, by checking the MingW Compiler's keyword, here's an interesting link that would point you in the right spot... so in theory you could have it this way
#ifdef __MINGW32__
/* we're in the simulator target */
#else
/* we're in the native target */
#endif
I use something like :
#ifdef SHP
# define CONFIG_SUPPORT_API_Osp 1 // bada
#endif
I wish there is also a define that tell sdk version or target api too ..
Use :
#ifdef _DEBUG
// Your code
#endif