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
Related
#define IS_PRODUCTION YES
/*****************************************************************************/
#if (IS_PRODUCTION) /* IS PRODUCTION */
#define MAIN_SERVER_URL #"http://www.xxxx.org/xxxx_live"
#else
#define MAIN_SERVER_URL #"http://www.xxxx.org/xxxx_test"
#endif
it doesn't seem to find IS_PRODUCTION as true. What is wrong in syntax?
Macros are not objective-C. There is no YES in the preprocessor, it is just an unknown literal (well, technically YES can be a macro, but it cannot be used in preprocessor conditions).
Some ways to fix that:
#define IS_PRODUCTION
#ifdef IS_PRODUCTION
#if defined(IS_PRODUCTION)
or
#define IS_PRODUCTION 1
#if IS_PRODUCTION
or
#define YES 1
#define IS_PRODUCTION YES
#if IS_PRODUCTION
but I recommend not to redefine YES. That's really not a good idea.
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
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
I should built and archive my application with Prod_URL and Stage_URL for our test team.
now i am using an Constant.h file and there is a code like;
//for stage
#define SERVICE_URL #"myStageUrl.com"
/*
//for prod
#define SERVICE_URL #"myProdUrl.com"
*/
And I always changing comment out lines to be able to build two different version of my app.
So now I wanna do it automatically.
I create two target like MyAppStage and MyAppProd. And I think I should write a Run Script for that to switch between these two #define lines. But I don't know how to write script.
Or are there any better way for that situation?
Thx,
If you have two separate targets you can place these defines in the project properties its self. To do that you go to your project properties. Click on the target you want to edit, click on the "Build Settings" tab and search for Preprocessor Macros. Define anything you want there and it will be visible for every class in that target.
Another option is to use the same Preprocessor Macros build setting and set a macro for STAGE. then in your Constant.h you can have something like:
//for stage
#ifdef STAGE
#define SERVICE_URL #"myStageUrl.com"
#else
//for prod
#define SERVICE_URL #"myProdUrl.com"
#endif
In your target for staging, add a preprocessor macro, something like STAGING_BUILD will do. Don't change the production target.
Now, in your code:
#ifdef STAGING_BUILD
//for stage
#define SERVICE_URL #"myStageUrl.com"
#else
//for prod
#define SERVICE_URL #"myProdUrl.com"
#endif
then only the required line will be compiled in based on the target selected to be built.
If I compile it to device or simulator, it works well. But when I do Product --> Archive, it errors:
Login.m
! Semantic Issue
Use of undeclared identifier 'kLogin_URL'
But this works on simulator and device
I am using Xcode version Version 4.6 (4H127). Here is the constant file.
#ifndef MyMobileApp_AllUrls_h
#define MyMobileApp_AllUrls_h
#ifdef QA
#define kLogin_URL #"https://b2bgateway.qa.mycompany.com/authenticate"
#define ktran_URL #"https://b2bgateway.qa.mycompany.com/.../lookup"
#define LOGIN_REQUEST_TIMEOUT 15.0f
#define TRAN_REQ_TIMEOUT 60.0f
#endif
#ifdef PROD
#define kLogin_URL #"https://b2bgateway.mycompany.com/authenticate"
#define ktran_URL #"https://b2bgateway.mycompany.com/.../lookup"
#define LOGIN_REQUEST_TIMEOUT 15.0f
#define TRAN_REQ_TIMEOUT 30.0f
#endif
#endif
The contents of -prefix.pch is
#import <Availability.h>
#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "AllUrls.h"
#endif
Appreciate your inputs.
Thanks
Make sure your build settings preprocessor macros include PROD under your release configuration.
Per your comment, Just wanted to make sure this is what you did.
#ifdef QA
#define kLogin_URL #"https://b2bgateway.qa.mycompany.com/authenticate"
#define ktran_URL #"https://b2bgateway.qa.mycompany.com/.../lookup"
#define LOGIN_REQUEST_TIMEOUT 15.0f
#define TRAN_REQ_TIMEOUT 60.0f
#else
#define kLogin_URL #"https://b2bgateway.mycompany.com/authenticate"
#define ktran_URL #"https://b2bgateway.mycompany.com/.../lookup"
#define LOGIN_REQUEST_TIMEOUT 15.0f
#define TRAN_REQ_TIMEOUT 30.0f
#endif