Application crash with memory warnings when NSLog enabled - ios

My application is frequently receiving memory warnings and crashes with I enable NSLog statements and run it via XCode 6.1. It works fine in release mode by disabling NSLog statements. I am not able to memory profile the app using instruments as even instrument hangs when I run with NSLog statements enabled.
Has anyone faced this issue and know of a workaround?
This is how I am defining a macro to enable logs when running in DEBUG mode.
#ifdef DEBUG
#define MYLOG(...) NSLog(__VA_ARGS__)
....
MYLOG(#"Log something");

I am using the following and It works fine for me.
#ifdef DEBUG
#define MYLOG(format, ...) NSLog(format, ##__VA_ARGS__)
#else
#define MYLOG(...)
#endif

Found the issue. It was not NSLog. Application was crashing in Debug mode only and it was because NSZombie was enabled. Once I disabled NSZombie, it worked!

Related

Disable iOS OSLog on release build

I want to disable OSLog for my iOS app (release build). I am not using OSLog in my app but I still see some logs in the console app logged by the apple frameworks (like libnetwork, Corefoundation, SystemConfiguration etc.,). Is there is a way to completely turn off all the logs for the app?
I added the below values to the environment variable but still, it disables the logs only when I ran the application from XCode however, I still see OSLog for my app on the console app when I launch it by clicking the App Icon.
OS_ACTIVITY_MODE=disable
Note: My app uses both Objective C and Swift programming language and disabled NSLog(Objective C) and print(Swift) and I do not have an issue with it. I want to disable all the logs including logs from the Apple framework for my release build.
just a quick solution but not the most comfortable..
#ifndef DEBUG
#define OSLog(FORMAT, ...) {}
#endif
if DEBUG mode is not used, which should be RELEASE then, OSLog() will be exchanged with void function content at compile time. Which will apply to code you wrote, not turning off Logs in general outside your sources scope.
To Disable OSLog on Release Builds
You could create a global function like:
func customLogger(_ category: String) -> OSLog {
#if DEBUG
return OSLog(subsystem: Bundle.main.bundleIdentifier!, category: category)
#else
return OSLog.disabled
#endif
}
For more detailed and advanced scenarios please check Apple's official documentation.

Condition #if DEBUG else if PRODUCTION not working in Swift

I am trying to use different environments for my application but facing issues doing it.
It's not the case that debug is not working the case is none of the variables are working.
I am attaching a screenshot which will make it easier to understand what is happening.
I am not able to access any of the environments.
I ran this code in viewDidLoad of initial view controller of my application and last else condition gets executed.
#if DEBUG
print("Environment is debug")
#elseif debug
print("Environment is debug")
#elseif Debug
print("Environment is Debug")
#elseif RELEASE
print("Release")
#elseif PRODUCTION
print("Environment is production")
#elseif PROD
print("Environment is PROD")
#else
print("Environment is can't find")
#endif
Adding few more images for better clarity regarding schemes and Xcode settings.
In my case the issue was solved by adding DEBUG as the debug Active Compilation Condition. I know it's already specified when you create a new project, but I don't remember if me or another team's member removed it (and why!). So I decided to put it here just in case someone else is facing the same scenario
I did research and setting compiler flags solved the problem.
Earlier they were blank and the way Xcode UI is I got confused how to edit them they looked disabled.
So what you have to do is double tap on the side of the flags or press enter and add the following values as I had attached the screenshot below.
DEBUG is the only default swift flag on a new project. You can create your own in your project build settings, Other Swift Flags.
Otherwise:
#if DEBUG
// This code will be run while installing from Xcode
#else
// This code will be run from AppStore, Adhoc ...
#endif

Xcode incorrectly "recognizing" iOS Simulator as actual Device

I'm using the camera and want to check if I'm using the iOS Simulator or an actual Device, so I put this statement in my code:
#if IOS_SIMULATOR
print("It's an iOS Simulator")
#else
print("It's a device")
#endif
However when I'm running the device in the iOS Simulator it actually prints out "It's a device".
Which is the opposite. Is there some other Xcode setting or flag I can check for this?
It seems as though I would have something selected saying "Even if it's the Simulator always run as if it's a device" you know?
I'm not sure where you're getting IOS_SIMULATOR from, but it's certainly not from Apple. I suggest you use Apple's APIs for doing this. Eg:
#include <TargetConditionals.h>
#if TARGET_OS_SIMULATOR
...
#else
...
#endif

Disable Parse Analytics during development

How do I disable Parse Analytics during development. I tried commenting out the setApplicationId: clientKey: call but as there are events being tracked throughout my code this causes an exception.
Parse doesn't have a native functionality for disabling analytics during development, but you can wrap your events code using an #ifdef - #else - #endif statement
#ifdef DEBUG
#else
[PFAnalytics trackEvent:#"eventName" dimensions:#{ #"parameter": #"value" }];
#endif
As long as you are running with DEBUG enabled (dev environments), this event tracker will not run.
You may also need to check the settings for your build to ensure it is DEBUG mode. See this answer for help:
Xcode / iOS: How to determine whether code is running in DEBUG / RELEASE build?

Use multiple crash reporter on iOS

We successfully use TestFlightLive as our crash reporter, but I think some features are missing. These missing features are in another crash reporter: Crashlytics, but as of now I'm not willig to switch crash reporters completely. So I wonder if it's possible to use these both crash reporters together in one app (which is meant to be in the app store in the future).
I run both TestFlight and Crashlytics together and they both report errors fine. Like Jens Kohl says above, it must be included after the TestFlight SDK is initialized. Here's my code:
#ifdef DEBUG
// setup testflight if in debug (ie dev) mode
[TestFlight takeOff:kTestFlightAPIKey];
#endif
[Crashlytics startWithAPIKey:kCrashlyticsAPIKey];
You can only use 1 crash reporting framework. The framework catching the crash lets the other framework either not catch it or get wrong data since there is already new code executed on the thread.

Resources