Can NSLog be disabled from appearing in device's console? [duplicate] - ios

This question already has answers here:
How do I disable NSLog?
(15 answers)
Closed 8 years ago.
I have a builded application that is running on device. I open device's console view in XCode's Organizer window. I assume (for the sake of this question) that NSLog(#"Some string") gets called.
Is there any way, may be an option in device, or application's settings, that would disable this log from appearing in console?
Edit: I'm not interested in replacing NSLog by other solution that can achieve this effect. The purpose of this question is to fully understand NSLog's functionality.

(Thanks to #MartinR for encouraging me to pull my finger out on this answer and to correctly identify that you cannot just close stdout/stderr, as the next open() will re-use those file descriptors, but to redirect stdout/stderr to the infamous /dev/null).
logControl.h:
#pragma once
extern void stopLogging();
extern void startLogging();
logControl.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
static int loggingStopped = 0;
static int oldStdout = -1;
static int oldStderr = -1;
void stopLogging() {
if (!loggingStopped) {
oldStdout = dup(1);
oldStderr = dup(2);
int devNull = open("/dev/null", O_WRONLY);
dup2(devNull, 1);
dup2(devNull, 2);
close(devNull);
loggingStopped = 1;
}
}
void startLogging() {
if (loggingStopped && oldStdout >= 0 && oldStderr >= 0) {
dup2(oldStdout, 1);
close(oldStdout);
oldStdout = -1;
dup2(oldStderr, 2);
close(oldStderr);
oldStderr = -1;
loggingStopped = 0;
}
}
This works at runtime, not compile time, which I believe is what you are asking. Simply call stopLogging() or startLogging() as required.
NOTE: There is no error-checking to speak of, so that could be improved perhaps.

Add this line given below in your .pch file in Xcode.
#define NSLog(...)
It will disable all NSLogs.
for more alternatives see the link

#if TARGET_IPHONE_SIMULATOR
//Simulator
#else
// Device
#define NSLog
#endif
Add this in your .pch file this will disable NSLog only for device alone not for simulator.

Add below code to .pch file
#ifdef DEBUG
# define NSLog(...) NSLog(__VA_ARGS__)
#else
# define NSLog(...) /* */
#endif
And in Build Settings, search "Preprocessor Macros" and remove "DEBUG=1" written in it.
and Thats it, you will not see any logs in your console now.

Related

What are the Malloc memory leaks shown in Instruments in Xcode, and how can I fix them?

I recently started working on optimizing the memory usage in my Swift application. When I started using the Leaks Instrument, I got over 100 "Malloc" leaks with no descriptions. I've looked around, but cannot find an explanation.
I'm running iOS 12.0 and Xcode 10.2
I went as far as commenting out all of the functions that were being called in my ViewDidLoad, and I'm still getting around 50 Malloc leaks.
I researched what causes memory leaks, and there's nothing in my code to suggest a leak, but I'm fairly new to memory management.
It's important for my app to not have leaks, so any help would be appreciated!
Let's say you have a very simple code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int mem(long int mem) {
char *buffer = malloc(sizeof(char) * mem);
if(buffer == NULL) {
return 1;
} else {
return 0;
}
}
int main(int argc, const char * argv[]) {
long int mem_to_alloc = 2;
for(int i=0; i<30; i++, mem_to_alloc *= 2) {
printf("Allocation: %d Allocating: %ld\n", i, mem_to_alloc);
if( mem(mem_to_alloc) == 1 )
break;
sleep(1);
}
return 0;
}
First of all, make sure to set proper configuration in Build Scheme
Once in Instruments choose Leaks
After you have run your code, you should see suspicious allocations with the calls stack (Stack Trace) on the right.

My first PIC32MX ISR not firing, code is hanging

I'm just getting started with a PIC32MX340F12, and MPLABX. My first attempt was to write a timer interrupt, so I worked with the datasheet, compiler manual, and examples and came up with the below. But it doesn't work... the interrupt never fires, and in fact if I leave both the timer interrupt enable (T1IE=1) and the general interrupt enable active ("ei"), it runs for a few seconds then hangs (says "target halted" in debug mode). If I remove either of those, it just runs indefinitely but still no timer interrupt. So I appear to have a pretty bad problem somewhere in my ISR syntax. Does it jump out at anyone?
Like I said I'm just getting started so I'm sure it's a pretty dumb oversight. And as you may notice I like to work as directly as possible with registers and compiler directives (rather than manufacturer supplied functions), I feel like I learn the most that way.
Thanks!
#include <stdio.h>
#include <stdlib.h>
#include "p32mx340f512h.h"
#include <stdint.h>
int x = 0;
int main(int argc, char** argv)
{
INTCONbits.MVEC = 1; // turn on multi-vector interrupts
T1CON = 0; // set timer control to 0
T1CONbits.TCKPS = 1; // set T1 prescaler to 8
PR1 = 62499; // set t1 period
TMR1 = 0; // initialize the timer
T1CONbits.ON = 1; // activate the timer
IPC1bits.T1IP = 5; // T1 priority to 5
IPC1bits.T1IS = 0; // T1 secondary priority to
IFS0bits.T1IF = 0; // clear the T1 flag
IEC0bits.T1IE = 1; // enable the T1 interrupts
asm volatile("ei"); // enable interrupts
while (1)
{
x++;
if (x > 10000)
{
x = 0;
}
}
return (EXIT_SUCCESS);
}
bool zzz = false;
void __attribute__((interrupt(IPL5AUTO))) T1Handler(void)
{
IFS0bits.T1IF = 0;
zzz = true;
}
Embedded systems are somewhat specialized, and this is a specific one I'm not familiar with.
However, from working with other systems, you may have to associate the Int Handler function address (T1Handler) with the interrupt it is handling. (Unless the framework you are using is doing that for you under the covers when building?)
Are all those names you are using automatically mapped for you by the build system?
If not, you may need to call some kind HW init or framework init at the top of main, before using them.
Some HW init/reset may be needed also, before the HW can be programmed.
Hope some of this helps.

No NSLog output in distributed app under iOS 10

In iOS 10 Apple has made a change that NSLog() output is not emitted in distributed apps (enterprise, app-store).
Note that when running from Xcode, NSLog() works fine.
Is there a way to force debug for all apps (very useful under beta testing phase)?
Some clues appear here: NSLog on devices in iOS 10 / Xcode 8 seems to truncate? Why?
However, can we have a clear implementation for this?
Our solution depends on two questions:
Are we compiling using Xcode 8 and up? If yes, the new os_log is recognized. If not, we must fall back to existing NSLog behavior.
Are we running under iOS-10 and up? If yes, we can use the new logger. If not, we must fall back to existing NSLog behavior.
We will find the answer to question [1] on compile time. For [2] we must test in runtime.
Here is the implementation:
mylog.h
//only used to force its +load() on app initialization
#interface MyLog:NSObject
#end
#if !__has_builtin(__builtin_os_log_format)
//pre Xcode 8. use NSLog
#else
//we need this include:
#import <os/log.h>
#endif
void myLog(NSString *format, ...);
#ifdef DEBUG
#define NSLog(f, ...) myLog(f, ## __VA_ARGS__)
#else
#define NSLog(f, ...) (void)0
#endif
mylog.m
#implementation MyLog
BOOL g_useNewLogger = NO;
+(void)load
{
NSOperatingSystemVersion os_ver = [[NSProcessInfo processInfo] operatingSystemVersion];
if (os_ver.majorVersion >= 10) {
g_useNewLogger = YES;
}
NSLog(#"Use new logger: %#", g_useNewLogger? #"YES":#"NO");
}
#end
void myLog(NSString *format, ...)
{
va_list args;
va_start(args, format);
#if !__has_builtin(__builtin_os_log_format)
//pre Xcode 8. use NSLog
NSLogv(format, args);
#else
//Xcode 8 and up
if (g_useNewLogger) { // >= iOS 10
NSString *nsstr = [[NSString alloc] initWithFormat:format arguments:args];
os_log(OS_LOG_DEFAULT, "%{public}s", [nsstr cStringUsingEncoding:NSUTF8StringEncoding]);
} else { // < iOS 10
NSLogv(format, args);
}
#endif
va_end(args);
}
If you want a drop-in solution to get the logs of your apps, I recommend you to take a look to a tool we have created. It's called Bugfender and what it does is that it send all the app logs to our server so you can check them on our site.
It's very useful while doing beta testing, because your users can test the app and if they find a problem you will get the information of everything they have done in the app.

With iOS, is it possible to detect when an iPhone is turned on?

It would be incredibly useful for a project I am working on that if, when the iOS device is turned on and boots up, I can save a timestamp of that occurrence. Is there any code I can run that will store this variable? If not, is there a way I can check without opening the app if an iPhone is on at a certain time?
Thanks!
Sorry for the confusion:
I want to make an app that has the capability to remember the last time an iOS device was turned on.
You can read the kern.boottime sysctl, which tells you when the system booted. I don't believe it would throw you out of the app store in this case:
#import <sys/sysctl.h>
- (time_t)bootTime
{
struct timeval boottime;
int item[2] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(boottime);
int st = sysctl(item, 2, &boottime, &size, 0, 0);
if (st < 0)
return -1;
return boottime.tv_sec;
}
No this is not possibe in iOS.

Any way to differentiate between code running on a iPhone simulator vs live device? [duplicate]

This question already has answers here:
How can I programmatically determine if my app is running in the iphone simulator?
(21 answers)
Closed 9 years ago.
I have some logic in my iOS application that I would like to execute differently when testing on an the iPhone simulator vs when its running on a live device.
Is there any way to determine in objective C whether the logic is being executed on one or the other?
Currently, I comment out some code before I deploy to my physical iPhone. Not convenient.
The reason behind the (slightly) different execution paths btw, is that my application utilizes data that is time/date dependent. On the simulator i have a static data set loaded so my testing takes that into account (i.e doesnt use current systems dates etc).
On the live device, the data is always fresh so no such issues.
It really should be known at compile time, as per TARGET_IPHONE_SIMULATOR macro. If you need to do a runtime check:
bool is_simulator()
{
NSString *model = [[UIDevice currentDevice] model];
return [model isEqualToString:#"iPhone Simulator"];
}
or without using objective C you could perhaps use sysctl as follows:
static int32_t sysctl_int32(const char* name)
{
int32_t val = 0;
size_t size = sizeof(val);
sysctlbyname(name, &val, &size, NULL, 0);
return val;
}
bool is_simulator()
{
int32_t cpu_type = sysctl_int32("hw.cputype");
return (cpu_type == CPU_TYPE_I386 || cpu_type == CPU_TYPE_X86_64)
}
Try
if (TARGET_IPHONE_SIMULATOR){
//Running on simulator
}else{
//Real one
}
Use
#if TARGET_IPHONE_SIMULATOR
// Using Simulator
#else
// Using device

Resources