通過重定向NSLog過濾WKWebView [Process] kill() returned unexpected error 1

網上有很多關於解決WKWebView錯誤日誌不停打印 [Process] kill() returned unexpected error 1 的文章,解決方法都是通過

1、Xcode menu 打開: Product > Scheme > Edit Scheme
2、在 Environment Variables 設置 OS_ACTIVITY_MODE = disable

這種做法是乾淨利落,但是系統其它錯誤日誌也被誤殺了,還導致NSLog無效。其實我們可以通過重定向NSLog,過濾掉不需要的信息,然後使用非標準錯誤流輸出日誌信息。下面是實現代碼:

Swift版本

#if DEBUG
private func hookSTDERR() {
	// 能連接到控制檯才允許重定向
    guard isatty(STDERR_FILENO) == 1 else {
        return
    }
    let pipe = Pipe()
    let pipeReadHandle = pipe.fileHandleForReading
    // 將標準錯誤輸出流重定向到新建的文件流
    dup2(pipe.fileHandleForWriting.fileDescriptor, STDERR_FILENO)
    
    let _ = NotificationCenter.default.rx
        .notification(FileHandle.readCompletionNotification, object: pipeReadHandle)
        .subscribe(onNext: {
            guard let data = $0.userInfo?[NSFileHandleNotificationDataItem] as? Data else {
                return
            }
    
            /// 過濾wk的錯誤信息(使用正則過濾,防止過濾掉重要信息)
            if var log = String(data: data, encoding: .utf8) {
                log = log.replacingOccurrences(of: "\\d+-\\d+-\\d+\\s\\d+:\\d+:\\d+\\.\\d+[-+]\\d+\\d.+\\[\\d+:\\d+\\]\\s\\[Process\\] kill\\(\\) returned unexpected error 1\\s?", with: "", options: .regularExpression)
                // 使用標準輸出流,輸出日誌信息
                print(log, terminator: "")
            }
            ($0.object as? FileHandle)?.readInBackgroundAndNotify()
        })
    pipeReadHandle.readInBackgroundAndNotify()
}
#endif

OC版本

#if DEBUG
void hookSTDERR() {
	// 能連接到控制檯才允許重定向
	if (isatty(STDERR_FILENO) == 0) {
		return;
	}
    NSPipe *pipe = NSPipe.pipe;
    NSFileHandle *pipeReadHandle = pipe.fileHandleForReading;
    // 將標準錯誤輸出流重定向到新建的文件流
    dup2(pipe.fileHandleForWriting.fileDescriptor, STDERR_FILENO);
    [NSNotificationCenter.defaultCenter addObserverForName:NSFileHandleReadCompletionNotification object:pipeReadHandle queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification * _Nonnull note) {
        NSData *data = note.userInfo[NSFileHandleNotificationDataItem];
        if (![data isKindOfClass:NSData.class]) {
            return;
        }
        
        NSString *log = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        
        /// 過濾wk的錯誤信息(使用正則過濾,防止過濾掉重要信息)
        log = [log stringByReplacingOccurrencesOfString:@"\\d+-\\d+-\\d+\\s\\d+:\\d+:\\d+\\.\\d+[-+]\\d+\\d.+\\[\\d+:\\d+\\]\\s\\[Process\\] kill\\(\\) returned unexpected error 1\\s?" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, log.length)];
        // 使用標準輸出流,輸出日誌信息
        printf("%s", log.UTF8String);
        
        [((NSFileHandle *)note.object) readInBackgroundAndNotify];
    }];
    [pipeReadHandle readInBackgroundAndNotify];
}
#endif

最後在AppDelegate裏面調用就好了。

#if DEBUG
    hookSTDERR()
#endif
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章