Наше решение зависит от двух вопросов:
- ли мы компилирования с помощью Xcode 8 и выше? Если да, то новый os_log распознается. Если нет, мы должны вернуться к существующему поведению NSLog.
- Мы работаем под управлением iOS-10 и выше? Если да, мы можем использовать новый регистратор. Если нет, мы должны вернуться к существующему поведению NSLog.
Мы найдем ответ на вопрос [1] во время компиляции. Для [2] мы должны тестировать во время выполнения.
Вот реализация:
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);
}