1 CocoaLumberjack
使用开源第三方库CocoaLumberjack。
2 hook
使用fishhook来hook系统的NSLog方法,具体原理及方法可见:Fishhook 学习笔记
(注意fishhook只能hook系统的c方法,自定义的不行,原理还是见上面的Fishhook学习笔记)
#import "ViewController.h"
#import "fishhook.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//定义rebinding 结构体
struct rebinding rebind = {};
rebind.name = "NSLog";
rebind.replacement = hookNSLog;
rebind.replaced = (void *)&nslogMethod;
//将上面的结构体 放入 reb结构体数组中
struct rebinding red[] = {rebind};
/*
* arg1 : 结构体数据组
* arg2 : 数组的长度
*/
rebind_symbols(red, 1);
}
//定义一个函数指针 用于指向原来的NSLog函数
static void (*nslogMethod)(NSString *format, ...);
void hookNSLog(NSString *format, ...){
format = [format stringByAppendingString:@"被勾住了"];
nslogMethod(format);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"原有NSLog函数");
}
3 dup2 函数和 STDERR 句柄
NSLog 最后写文件时的句柄是 STDERR,我们可以通过重定向的方式将输出路径改变。参考: iOS日志获取和实时浏览器显示日志
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self redirectSTD:STDERR_FILENO];
}
- (void)redirectSTD:(int )fd{
NSPipe * pipe = [NSPipe pipe] ;
NSFileHandle *pipeReadHandle = [pipe fileHandleForReading] ;
int pipeFileHandle = [[pipe fileHandleForWriting] fileDescriptor];
dup2(pipeFileHandle, fd) ;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(redirectNotificationHandle:)
name:NSFileHandleReadCompletionNotification
object:pipeReadHandle] ;
[pipeReadHandle readInBackgroundAndNotify];
}
- (void)redirectNotificationHandle:(NSNotification *)nf{
NSData *data = [[nf userInfo] objectForKey:NSFileHandleNotificationDataItem];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
//这里可以做我们需要的操作,例如将nslog显示到一个textview中,或者是存放到另一个文件中等等
//self.logTextView.text = [NSString stringWithFormat:@"%@\n%@",self.logTextView.text, str];
NSRange range;
//range.location = [self.logTextView.text length] - 1;
range.length = 0;
//[self.logTextView scrollRangeToVisible:range];
[[nf object] readInBackgroundAndNotify];
}
网友评论