如何在Xcode中筛选控制台输出

19
在我的iOS项目中,我使用了一个第三方库,但是它会在控制台输出中大量地产生垃圾信息。我能否对调试输出应用任何过滤方式?

1
这可能不是一个真正的解决方案,但是MCLog是一款XCode插件,可以实现输出过滤。 - david
@david 谢谢,我应该把这个评论选为最佳答案,因为MCLog正好符合我的需求。 - ArtFeel
我已将我的评论复制为答案。 - david
4个回答

5
如果库正在使用NSLog,您可以重新定义它并在来自库的日志消息时丢弃它。示例代码:
#define NSLog(args...) [[Logger singleton] debugWithLevel:kDebug line:__LINE__ funcName:__PRETTY_FUNCTION__ message:args];

// poor man's nslog
@interface Logger : NSObject

typedef enum {
    kTrace=0, kDebug=1, kInfo=2, kWarn=3, kError=4, KSilent=5
} LoggerLevel;


// ...

@implementation Logger

+(Logger *)singleton {
    static dispatch_once_t pred;
    static Logger *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[Logger alloc] init];
        shared.logThreshold = kTrace;
    });
    return shared;
}
-(void) debugWithLevel:(LoggerLevel)level 
                  line:(int)line 
              funcName:(const char *)funcName 
               message:(NSString *)msg, ... {

    va_list ap;         
    va_start (ap, msg); 
    msg = [[[NSString alloc] initWithFormat:msg arguments:ap] autorelease];
    va_end (ap);        

     msg = [NSString stringWithFormat:@"%s %50s:%3d - %@", levelName[level], funcName, line, msg];

    // ... filter by class name ...

    fprintf(stdout,"%s\n", [msg UTF8String]);
}
@end

请注意,funcName 包含发送消息的类名和方法。如果库里的类有前缀,且它是一个好公民,那么当 className 以该前缀开始时,请忽略输出。否则,在 fprintf 行之前必须加载该库中的类列表并进行检查。
当然,这不会像 NSLog 一样将日志复制到 syslogd 中,但谁在乎呢。:P

3

1
是啊...不再起作用了。Github的问题也表明了这一点,似乎没有人在意。 - Radu Simionescu

3

这要看您是直接在项目中使用第三方库的源代码还是二进制库。

如果您使用的是源代码,建议检查它们用于记录消息的方式。可能有一种方法可以减少冗余信息。如果他们仅使用NSLog,那么唯一的选择就是重新定义NSLog以进行一些过滤,正如Jano所建议的那样。

如果他们使用像printf之类的低级函数,则最好的选择是将它们替换为自己的自定义日志宏,例如:

#ifdef DEBUG_3P
    #define LOG_3P(str) NSLog(@"%s", str)
#else
    #define LOG_3P(str) /* nothing */
#endif

然后,将printf("a c string message")替换为LOG_3P("a c string message")。您需要自定义解决方案,调整宏参数甚至添加几个宏以适应您的情况。并进行一些搜索和替换,直到它正常工作。
当您想查看第三方库日志时,只需在构建设置中定义DEBUG_3P为C标志:-D DEBUG_3P,否则它将被静音。
如果您正在使用二进制库,则可以使用其发布配置构建它,将日志详细程度禁用或降低到最低。

我使用用C语言编写的源代码库,它使用printf()、vprintf()和puts()进行日志记录。 - ArtFeel
在这种情况下,除非您使用自己的日志记录宏进行替换,否则恐怕您无法轻松地截取输出。请查看我的更新答案。 - djromero

1
对于Swift,我编写了一个围绕print()的包装器,可以实现这一点。请参见此处: https://github.com/SebastianMecklenburg/TagLog
它通过在调试消息中添加标签,然后通过这些标签过滤输出来工作。它完全在代码中工作,不需要Xcode插件。

这会过滤掉通过 print() 命令发送到控制台的第三方文本吗? - Mihai Fratu
1
Github链接现在是404。 - teradyl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接