Debug mode on iOS - objective-c

been researching this a while and not sure entirely what to do.
I want to allow users to switch debug mode either on or off. With debug mode on NSLogs will be printed to console.
currently I can set debug mode on or off in the build settings using a preprocessor (DEBUG) and I use the following code to "block" NSLogs.
#ifdef DEBUG
NSLog(#"If you can see this then debug is on");
#endif
I have created a toggle switch in the settings page to get input from the user but I don't know how to use this input to then undefined/redefine DEBUG. Any ideas?
I am not sure if this is even possible so any alternate solutions would also be appreciated.
Many Thanks :)

You should not use preprocessor directives: using #ifdef DEBUG means that, if DEBUG is not defined, that piece of code doesn't get compiled at all.
You should instead replace preprocessor directives with a simple if statement that check a global variable (or, at least, that may be a solution).

I believe your code block would only check if you are building for debug or release and will build accordingly.
You can build it on a device it will be on release mode , I don't think it is possible to run the simulator in release mode otherwise.
Maybe manually building the application for simulator and moving the packed file to run only on simulator without running xcode, but it will not be reasonable I guess.

Related

Facebook iOS 3.7 FacebookAppId

I just installed from pkg the SDK 3.7 for Facebook.
I see that I need to put there a value for FacebookAppId. However I have 2 apps: one for testing and one for production.
Since I need to support variables for Debug and Release, I am using an Environment file which determines the value based on the configuration value. (Debug or Release)
How can I "tell" the SDK to use the relevant one for each release type, without changing it manually when building it?
I didn't check in the source code. Just the compiled one.
Is there a way to do it?
You can use the Preprocessor macros over here..
How to use it :
Go to Build settings of your project.
Search "Preprocessor macros". Here define your macros like for eg FBDebugAPPID for debug moed & FBReleaseAPPID for release mode.
FBSettings class used to override the default facebook AppId.
Then after add below code in your delegate method..
#if defined(FBDebugAPPID)
**Use your debug app id**
[FBSettings setDefaultAppID:#"DEBUGAPPId"]
#elif defined(FBReleaseAPPID)
**Use your release app id**
[FBSettings setDefaultAppID:#"RELEASEAPPId"]
#endif
Hope it resolve your problem..
You can change you enviornment.plist variables by adding a run script build phase
To add a Run Script Build Phase in Xcode
Select your application target in your project, then select "Build Phases".
In the menu bar, click "Editor", select "Add Build Phase", and then click on "Add Run Script Build Phase".
You should now see a Run Script section in the middle of your Build Phase options, as shown above.
Inside the body of the Run Script Build Phase, paste in the script.
#!/bin/bash
if [ "${CONFIGURATION}" = "Release" ]; then
/usr/libexec/PlistBuddy -c "Set :FacebookAppID 321" "$INFOPLIST_FILE"
else
/usr/libexec/PlistBuddy -c "Set :FacebookAppID 321" "$INFOPLIST_FILE"
fi
Here's a simpler approach,
Recent Xcode project templates already have a DEBUG=1 macro defined for the Debug build configuration.
You can use it in combination with #ifdef
#ifdef DEBUG
#define FACEBOOK_APP_ID #"FB_DEVELOPMENT_ID"
#else
#define FACEBOOK_APP_ID #"FB_PRODUCTION_ID"
#endif

Build-time variables with XCode

I have the following scenario:
A Jenkins server which builds my iOS XCode project
The application sources data from a URL that needs to point to a different location depending on whether the build is for production or development
I need to be able to specify, at build-time, which environment I want to build the application for such that the URL used in the code (re: #define DATA_URL #"http://...") is proper for the environment being built for.
I do something simpler and to do this we set a macro in the build-settings under the header Preprocessor Macros then for each type of build (DEBUG, RELEASE, etc) set something like (DEBUG) APP_CONFIG=1 and for (RELEASE) APP_CONFIG=2 and so on for any others you have. Then in your ***-Prefix.pch you can do something like (Note this doesn't have to go in ***-Prefix.pch it can go anywhere in your code)
#if(APP_CONFIG==1)
#define DATA_URL #"http://..."
#else
#define DATA_URL #"http://..."
#endif
I asked something simpler a while a go here is the link Settings bundle for iPhone app
Hope this helps if it is not what you were looking for comment and I will try to amend best to help.

OCMock Failing at runtime

I'm trying to use OCMock for the first time in my test cases. It's a Mac project, built on and targeting Lion, in Xcode 4.3. The main app and the test bundle both have ARC turned on, and so every time I execute the tests I see the following log message:
GC: forcing GC OFF because OBJC_DISABLE_GC is set
That's fine, as I'm using ARC so I don't care about GC. When I build my unit tests, linked against the latest stable release of OCMock (2.0.1), the build has no issues. At runtime, after the above log statement, I get the following:
The test bundle at /Users/___/Library/Developer/Xcode/DerivedData/___-ayizwpehemunvodsdvczckkvarsh/Build/Products/Debug/___Tests.octest could not be loaded because its Objective-C runtime information does not match the runtime information required by the test rig. This is likely because the test rig is being run with Objective-C garbage collection disabled, but the test bundle requires Objective-C garbage collection. To enable Objective-C garbage collection for the test rig, run it in an environment without the OBJC_DISABLE_GC environment variable.
2012-03-06 10:29:32.812 otest[8486:203] *** NSTask: Task create for path '/Users/___/Library/Developer/Xcode/DerivedData/___-ayizwpehemunvodsdvczckkvarsh/Build/Products/Debug/___Tests.octest/Contents/MacOS/___Tests' failed: 22, "Invalid argument". Terminating temporary process.
The message implies that garbage collection is the most common culprit, but as mentioned, there is no way I'm using GC. So, what other settings could be messing me up at runtime? I didn't think I'm doing anything atypical, and I've looked through my test project's settings to be sure, and didn't see anything weird.
Update
I was able to reproduce this with a new empty project.
Create a new project and have it create unit tests, with ARC enabled
Clear the Test Host setting from the unit test bundle's build settings
Link to the OCMock framework
Execute the tests, and witness the same error I reported above
Also, when I turn off ARC and make garbage collection Required, then clang reports a mach-o linker error, so the build doesn't succeed. If I remove the link to the OCMock framework, it builds fine. This supports my initial thought that the problem lies somewhere other than garbage collection.
I found the answer, after a day of searching everything I could think of, in the Hamcrest tutorial (reading more carefully through the OCMock tutorial linked from OCMock.org, it's mentioned there, too). For some reason, Hamcrest's and OCMock's frameworks need to be copied to the products directory. Then everything works like a charm.
Go to the settings for your Tests Bundle
Go to the Build Phases tab
Click the Add Build Phase button, and select Add Copy Files
Set the new Copy Files build phases' Destination to Products Directory
Drag OCMock.framework from the project outline into the list of files for the phase
Drag the Copy Files phase above the Run Script phase
Execute your tests as usual

How can I add an #ifdef DEBUG to Xcode?

I have some code in a project which should never be used in the release build, but is useful when testing. I'd like to do something like this:
#ifdef DEBUG
// Run my debugging only code
#endif
Where do I add the DEBUG setting in Xcode 4? I tried putting it in the "Edit Scheme" under Run MyApp->Arguments Passed On Launch, but it didn't work. Alternatively, is there a flag already available for this?
In recent Xcode project templates there’s already a DEBUG=1 macro defined for the Debug build configuration (in the Preprocessor Macros section). You can test it using the #if preprocessor directive.
I usually add my -DDEBUG=1 to the OTHER_C_FLAGS section in my XCode 4 project's build settings.
And yes, they can even discriminate between Debug / Release / ADHOC / Store builds.

XCode Build Results: why is it so amazingly complex even for a hello world console app?

I have looked at build result for a simple hello world console app to see command line for compilation. Why is it so complex ? How can I then automate things if it is such complex ?
If you intend to automate builds of Xcode projects, use xcodebuild(1).
Your xcodeproj file contains all of the settings that you would need to specify on the command line if you were to call gcc directly. If you run xcodebuild all you need to do is specify your xcodeproj file, the target, the configuration, and the SDK to use. Everything else is done automatically.
Run "man xcodebuild" for more information.
XCode specifies an immense number of command line options for the compiler and linker with fully qualified path names. When working at the command line you'll frequently use defaults instead of specifying all the options the IDE does. Make or some other build tool is your friend for automation.