1

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?

Community
  • 1
  • 1
ishahak
  • 6,585
  • 5
  • 38
  • 56

2 Answers2

0

Our solution depends on two questions:

  1. 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.
  2. 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);
}
ishahak
  • 6,585
  • 5
  • 38
  • 56
0

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.

ventayol
  • 635
  • 4
  • 16