Where should I place my global macros? - ios

Where should I place such debugging macros, I want to use it as gloabl.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( #"<%p %#:(%d)> %#", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
Since prefix.pch has been removed in Xcode 6.

Create one Constant.h file only.
import view controllers, macros etc that need to be imported for whole application.
Use this in viewcontroller like this :
#import "Constant.h"

If you want to use macros in a Project, just add them in "Preprocessor Macro -> Debug" under "Build Settings" of your project.
And if you want to use the macros across project, you can create a Constant.h file as suggested by Prince.

Related

Header file not executing if else case

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

Calling Obj-C method from C

I've got a library written in C, where I need to push a call to a method written in Obj-c.
I don't want to modify the original code too much, so I decided to create a "bridge" class to handle the calls between C and ObjC:
DRMBridge.h
#ifndef DRMBridge_h
#define DRMBridge_h
#include "DRMBridgeObjC.h"
void bridge_test();
#endif
DRMBridge.c
#import "DRMBridge.h"
void bridge_test() {
ctest();
}
Above is compiled as C
Now here's my objc code:
DRMBridgeObjC.h
#ifndef DRMBridgeObjC_h
#define DRMBridgeObjC_h
#import <Foundation/Foundation.h>
#interface DRMBridgeObjC : NSObject
+(void) test;
#end
void ctest();
#endif
DRMBridgeObjC.m
#import "DRMBridgeObjC.h"
#implementation DRMBridgeObjC : NSObject
+(void) test {
NSLog(#"OH YEAH!");
}
#end
void ctest() {
[DRMBridgeObjC test];
}
Quite simple.
In the C library I want to call my code from I've added:
#include "DRMBridge.h"
into the .h file and
bridge_test();
in .c file.
Now the best part, when I compile I get:
In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridge.c:5:
In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridge.h:8:
In file included from /Users/krystian/projects/mdb-reader-lib/reader-Include/ios/MDBReader/Class/DRM/DRMBridgeObjC.h:12:
In file included from /Applications/Xcode64.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:8:
/Applications/Xcode64.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.4.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:400:1: error: expected identifier or '('
#class NSString, Protocol;
^
[...]
I went looking, and found this: ios - Parse Issues in NSObjCRuntime, NSZone, and NSObject
However my pch file looks like this:
#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>
#endif
I think the issue I have is that the C compiler tries to compile my ObjC file first, instead of the other way around.
I've tried changing the order of files inside Compile Sources to make sure that my .m file is above .c file, but still no go.
Something else I have found which made me lost:
when I follow this answer: https://stackoverflow.com/a/20461780/487605 and change the library itself to .m, and call [DRMBridgeObjC test] code from there - it works.... Compiles fine, no errors given, works fine.
This implies to me, that there's something screwed up with my DRMBridge, but what?
Thanks
Krystian
You've seen the solution already. Use #ifdef __ OBJC__ in your Objective-C header file so that only the plain C bits are compiled when including the file from C
DRMBridge.h
#ifndef DRMBridge_h
#define DRMBridge_h
#include <CoreFoundation/CoreFoundation.h> //or put in .pch
CF_EXPORT void bridge_test();
#endif
DRMBridge.m
#import "DRMBridge.h"
#import "DRMBridgeObjC.h"
void bridge_test() {
ctest(); //or [DRMBridgeObjC test]; if you like
}
Thats all. And you can include DRMBridge.h in whatever you like: in .c, in .m, in .cpp.

XCode: Check destination platform with define

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

How can I declare a config.h file, add it to my App-Prefix.pch, and then use it globally in my app?

I want to create a Config.h file to house all my static const strings that should be global to my application.
I've created a new Config.h file, but there are a few things I'm unaware of.
1) How do I declare variables. A or B?
A)
#define hotelURLString4 = #"http://blah.herokuapp.com/api/v1/hotels/";
B)
static NSString * const hotelURLString2 = #"http://blah.herokuapp.com/api/v1/hotels/";
2) I can't seem to use this file. If I try to import the Config.h directly into a file of mine, I get a "Config.h file not found" error in xcode. If I include it in my AppName-Prefix.pch up at the top via...
#import <Availability.h>
#import "Config.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>
#endif
That does not seem to work either. How do I do this.
3) How do I access the variable declared/defined. Do I call Config.hotelURLString, or [Config hotelURLString]... or how do I access it?
===================================================================
============================ UPDATE ===============================
1) I created my header like this... am I not doing something correctly, because I tried again and it won't work either.
2) This is my AppName-Prefix.pch file.
#import <Availability.h>
#import "Config.h"
#import "MyHeader.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>
#endif
3) Here is my Project Navigator
To answer question 1, method B is probably better, although you should name your variable more like:
kHoteUrlString2
And preferably something more descriptive then just the numbers, but the main point here is the lower case k and the uppercase first letter. This is a C/ObjC naming convention for constants.
As for question 2, it sounds like your file isn't actually in the project. Some more details are needed to answer this part of the question, and I'll update my answer if the question has more details added.
As for question 3, you use the variable exactly as you would as if you had declared it at the top of whatever file you're using. Objective-C doesn't have namespaces.

Using DebugLog() instead of NSLog()

i want to use DebugLog() to print values instead of NSLog(). I believe DebugLog() is more efficient. But i am not able to use it in my project(doesn't appear in prompt). I believe we have to set something in Build settings for that. Does anyone have any idea about this?
Thanks.
DebugLog() is not a supported method in objetice-c, if you want to implement it yourself, do something like this:
#ifdef DEBUG
#define DebugLog(s, ...) NSLog(s, ##__VA_ARGS__)
#else
#define DebugLog(s, ...)
#endif
Taken from here:
DebugLog Format string is not a string literal
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((#"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DLog(...)
#endif
To call NSLog only for the debug build:
#ifdef DEBUG
NSLog("Debugging");
//or any other statement
#endif
(This will be called only when the build configuration is 'debug' in your scheme)

Resources