Ras*_*sto 5 logging nslog ios uitextchecker swift
我有一个使用UITextCheckerApple提供的课程的应用程序.这个类有以下错误:如果iOS设备离线(通常是我的应用程序),每次我调用一些UITextChecker方法时,它会记录到控制台:
2016-03-08 23:48:02.119 HereIsMyAppName [4524:469877] UITextChecker sent string:isExemptFromTextCheckerWithCompletionHandler: to com.apple.TextInput.rdt but received error Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.TextInput.rdt was invalidated."
Run Code Online (Sandbox Code Playgroud)
我不希望此消息发送垃圾邮件.有没有办法从代码中禁用日志记录?我会在调用任何UITextCheckers方法之前禁用日志记录,然后重新启用它.或者是否有任何方法可以选择性地禁用每个类的日志记录(如果基础类不是我的,则为事件)?或任何其他解决方案?
警告:这个答案使用了私有但尚未记录的Cocoa C函数_NSSetLogCStringFunction()和_NSLogCStringFunction().
_NSSetLogCStringFunction()是Apple创建的用于处理实现功能的接口NSLog.它最初是为WebObjects公开,以挂钩到NSLogWindows机器上的语句,但仍然存在于今天的iOS和OS X API中.它在本支持文章中有记录.
该函数接受带有参数的函数指针,const char* message要记录的字符串,unsigned length消息的长度以及BOOL withSysLogBanner切换标准日志记录横幅的a.如果我们为日志创建我们自己的钩子函数实际上没有做任何事情(一个空的实现而不是fprintf像NSLog幕后一样调用),我们可以有效地禁用你的应用程序的所有日志记录.
Objective-C示例(或带有桥接头的Swift):
extern void _NSSetLogCStringFunction(void(*)(const char*, unsigned, BOOL));
static void hookFunc(const char* message, unsigned length, BOOL withSysLogBanner) { /* Empty */ }
// Later in your application
_NSSetLogCStringFunction(hookFunc);
NSLog(@"Hello _NSSetLogCStringFunction!\n\n");  // observe this isn't logged
Run Code Online (Sandbox Code Playgroud)
可以在YILogHook中找到此示例实现,它提供了一个接口,用于向任何NSLog语句(写入文件等)添加块数组.
Pure Swift示例:
@asmname("_NSSetLogCStringFunction") // NOTE: As of Swift 2.2 @asmname has been renamed to @_silgen_name
func _NSSetLogCStringFunction(_: ((UnsafePointer<Int8>, UInt32, Bool) -> Void)) -> Void
func hookFunc(message: UnsafePointer<Int8>, _ length: UInt32, _ withSysLogBanner: Bool) -> Void { /* Empty */ }
_NSSetLogCStringFunction(hookFunc)
NSLog("Hello _NSSetLogCStringFunction!\n\n");  // observe this isn't logged
Run Code Online (Sandbox Code Playgroud)
在Swift中,您也可以选择忽略所有块参数而不使用hookFunc如下所示:
_NSSetLogCStringFunction { _,_,_ in }
Run Code Online (Sandbox Code Playgroud)
要使用Objective-C重新开启日志记录,只需将其NULL作为函数指针传入:
_NSSetLogCStringFunction(NULL);
Run Code Online (Sandbox Code Playgroud)
使用Swift的东西有点不同,因为如果我们尝试传入nil或nil指针(NULL在Swift中不可用),编译器会抱怨类型不匹配.为了解决这个问题,我们需要访问另一个系统函数,_NSLogCStringFunction获取指向默认日志记录实现的指针,在禁用日志记录时保留该引用,并在我们想要重新开启日志记录时设置引用.
我通过添加NSLogCStringFunc typedef:清理了Swift的实现:
/// Represents the C function signature used under-the-hood by NSLog
typealias NSLogCStringFunc = (UnsafePointer<Int8>, UInt32, Bool) -> Void
/// Sets the C function used by NSLog
@_silgen_name("_NSSetLogCStringFunction") // NOTE: As of Swift 2.2 @asmname has been renamed to @_silgen_name
func _NSSetLogCStringFunction(_: NSLogCStringFunc) -> Void
/// Retrieves the current C function used by NSLog
@_silgen_name("_NSLogCStringFunction")
func _NSLogCStringFunction() -> NSLogCStringFunc
let logFunc = _NSLogCStringFunction() // get function pointer to the system log function before we override it
_NSSetLogCStringFunction { (_, _, _) in } // set our own log function to do nothing in an anonymous closure
NSLog("Observe this isn't logged.");
_NSSetLogCStringFunction(logFunc) // switch back to the system log function
NSLog("Observe this is logged.")
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1412 次  |  
        
|   最近记录:  |