I have an app that is making use of UITextChecker
class provided by Apple. This class has a following bug: If the iOS device is offline (expected to be often for my app) each time I call some of UITextChecker
s methods it logs following to console:
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."
I do not want to have logs spammed by this messages. Is there a way to disable logging from code? I would disable logging before call to any of UITextChecker
s methods and reenable it afterwards. Or is there perhaps any way how to disable logging selectively per class (event if it is foundation class not mine)? Or any other solution?
Warning: This answer uses the private-yet-sort-of-documented Cocoa C functions
_NSSetLogCStringFunction()
and_NSLogCStringFunction()
._NSSetLogCStringFunction()
is an interface created by Apple to handle the implementation function forNSLog
. It was initially exposed for WebObjects to hook intoNSLog
statements on Windows machines, but still exists in the iOS and OS X APIs today. It is documented in this support article.The function takes in a function pointer with the arguments
const char* message
, the string to log,unsigned length
, the length of the message, and aBOOL withSysLogBanner
which toggles the standard logging banner. If we create our own hook function for logging that doesn't actually do anything (an empty implementation rather than callingfprintf
likeNSLog
does behind-the-scenes), we can effectively disable all logging for your application.Objective-C Example (or Swift with bridging header):
An example implementation of this can be found in YILogHook, which provides an interface to add an array of blocks to any
NSLog
statement (write to file, etc).Pure Swift Example:
In Swift, you can also chose to ignore all of the block parameters without using
hookFunc
like so:To turn logging back on using Objective-C, just pass in
NULL
as the function pointer:With Swift things are a little different, since the compiler will complain about a type mismatch if we try to pass in
nil
or anil
pointer (NULL
is unavailable in Swift). To solve this, we need to access another system function,_NSLogCStringFunction
, to get a pointer to the default logging implementation, retain that reference while logging is disabled, and set the reference back when we want to turn logging back on.I've cleaned up the Swift implementation of this by adding a
NSLogCStringFunc
typedef
: