Xcode 8 preprocessor Macros? - ios

I am working with multiple targets in Xcode 8.2, Everything is good except handling files.
To import files, I have used different pch for each target but facing issues in using different class files.
How to work with other target files in the source, it throws an error on build app. When I try to add Preprocessor Macros in Build Settings but I can't find the Preprocessor Macros section in Xcode 8. Is there any alternative to this? please suggest some other approaches to handle different target files in the same source.
Thanks in Advance.

Select the target and go to build setting.
There search for "Preprocessor Macros" you will be able to find out.
Set the macros for particular target.
Use #ifdef in the code to check whether macros is defined or not, based on macros definition write the code for specific target.
That particular code will be reflected to that target only.

Related

Preprocessor Macros in Xcode 7.3 for targets

If I create a new project in Xcode 7.3 the "Preprocessor Macros" setting only appears for the project. It doesn't appear in the build settings for any of the targets in my project.
How do you create a preprocessor macro for a target only in a project in Xcode 7.3?
When you use the default view in Xcode (Basic), you only see a list of settings that are changed. When you create a new scheme, you have few (or no, can't remember) changed settings, and consequently wouldn't see the Preprocessor Macros region. Change your view to Advanced, and everything should become visible.
I think you can alternatively search the name directly, and that should pull it up too. I can't remember offhand, though, and I'm not at my Mac at the moment.

Building Cocoa touch framework with c++11 code

I am trying to make an iOS framework. My code includes c++11 features.
When I build the framework target I get errors such as:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/ctime:56:9: No member named 'clock_t' in the global namespace
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/ctime:58:9: No member named 'time_t' in the global namespace; did you mean 'size_t'?
How can I resolve this? Thanks.
UPDATE:
Here is my Apple LLVM 6.0 - Language-c++ settings:
Regular iOS project with that c++11 code compiles without errors.
you need to explicitly add libc++ as a linked library under general tab.
I don't know how far it will work fine in your scenario. I got similar kind of error when I tried to compile and build so. I will share what I did :
1.Goto your project Build Settings.
2.Click Build Settings.
3.Search for Apple LLVM 6.0 - Language-c++ .
4.set c++ standard library as libstdc++ .
Then try compile the project.
This might not the exact solution.
I just shared what worked for me when I am facing the similar kind of errors as yours.
Thank you!
Have you tried setting the C++ Language Dialect to C++11? It's in the same place as the C++ standard library setting:
Go to Build Settings
Select your Target, and click Build Settings.
Search for Apple LLVM 6.0 - Language-C++
Set C++ Language Dialect to C++11.
You might also have to set the C++ Standard Library to libc++.
Xcode adds all headers to the "Headers" build phase by default. So, I solved my issue by removing all unnecessary C++ headers from the build phase.

include header based on xcode scheme

My project uses a Settings.h to store common configuration settings like the server url etc. I have been tasked to create a new app from this code where only few parameters such as the server url , icon etc are different.
I have a new target in my xcode workspace for this. I have 2 Settings.h in separate folders like
awesomeProject/Settings/Settings.h
oldProject/Settings/Settings.h
The Settings.h is included in a few places in the project (not loaded via .pch). I have tried setting header search path for both the targets and this didn't work (as in the compiling awesomeProject target included the oldProject's Settings.h).
Is there a way to #include Settings.h based on the target without resorting to sprinkling #ifdef .. #endif constructs ?
If I understand right and you have separate targets to that need to include different header files so you should be able to set the 'Header Search Paths' differently and get the correct file. You said you tried this but you might want to try doing a clean and full rebuild.
I would try to leverage preprocessor to accomplish your goal. One option is to define in build settings for each target macro SETTINGS_H, which will be "awesomeProject/Settings/Settings.h" or "oldProject/Settings/Settings.h" depending on the target. Then in source code you can #include SETTINGS_H. Of course, you might need to tweak header search path to be able to find each header.
Honestly speaking, #include SETTINGS_H is a tad ugly for my taste, so I prefer another approach. You can keep single "Settings.h" file, but use macros for constant values. For example, in "Settings.m"
NSString *const kServerURL = SERVER_URL;
and in target build settings add to GCC_PREPROCESSOR_DEFINITIONS
SERVER_URL='#"http://stackoverflow.com"'
You might need to play with quotation marks to achieve the desired effect. To organize project better, you can move macros' definitions to .xcconfig file and keep separate .xcconfig files for each target.

Check for framework's existence at compile time?

I'm working on an open-source project that can optionally use a closed-source framework. If the closed-source framework is included in the project, there will be additional functionality. But if the framework isn't included in the project, the project should still compile properly.
How do I check at compile-time if the framework is included in the project?
Basically, I want to do something like this:
#ifdef _MY_FRAMEWORK_EXISTS
#import <MyFramework/MyFramework.h>
#endif
I've seen older questions from 2 years ago like this one, but no answer has surfaced so I might be missing something new now.
I DON'T want to check at run-time via NSClassFromString(), because this will fail at compile time when I try to import MyFramework and it doesn't exist.
You can check for the presence of a header file using the __has_include language extension.
http://clang.llvm.org/docs/LanguageExtensions.html#include-file-checking-macros
However, that only tells you if the header file is installed. It can't tell you if "Link Binary With Libraries" has linked to its framework.
I recommend reading the Mac Developer Library : Framework Programming Guide (which includes a section on Weak Linking).
What do you mean by "exists" or "included in the project"? Do you mean added to the "Link Binary With Libraries" build phase (as described by Including Frameworks)? All that does is affect the linking, not the compilation, build phase. To see this, build. Then, search for -framework in the build log of Xcode's Log Navigator.
So, yes, if you want to affect the compilation of the code you provided, you could manually define the macro _MY_FRAMEWORK_EXISTS.
I don't really understand what you are trying to do. Can you explain what you want at a higher level? Perhaps, there's a better way to go about it.
"Minimal overhead" is nice, but too much magic might be confusing. For example, Xcode's magic hides what really happens when including a framework.
I also recommend checking out how the Facebook SDK for iOS works for high & low-level ideas. It might do the kinds of things you want to do.

How to change icon files with code constant on xCode?

I'm building an app that has a Free version and Paid version.
The difference between the apps are only a define line of some constant in the code (it creates the code needed to add on each app).
I want the icons to change too according to this definition. Does someone knows how can I do that? can I choose for example between different info.plist files using code generated?
Please help.
You want to setup a duplicate Target of your main target for your lite version. In this secondary target, it should be identical except for a PREPROCESSOR MACRO that you add like LITE_VERSION. It should also point to a different info.plist
Then, in the code at compile time, you can use #ifdef LITE_VERSION to compile Lite code vs Reg Code when you compile for that target.

Resources