当前位置: 首页 > news >正文

iOS 收集打印日志

可以将要在Xcode 控制台打印的日志写在沙盒,最后导出分享,进行问题分析。

正式版本不建议使用,避免增加用户内存。配合解决顽固 Bug 可以通过该方法收集打印日志

.h头文件

@interface LogManager : NSObject
+ (FSLogManager *)shareInstance;
- (void)redirectNSlogToDocumentFolder;
- (NSString *)logDirPath;
- (void)clearAllLog;
- (float)sizeOfLogs;
@end

.m实现文件

#import "LogManager.h"
#import <UIKit/UIKit.h>#define LOG_TIME_FORMAT @"yyyy-MM-dd HH:mm:ss.SSS"
#define LOG_QUEUE_ID "log_queue"static LogManager *manager = nil;/// 是否运行收集日志,如果为 YES , 将不会在日志控制台打印。
static BOOL const kAllowSaveLog = YES;@implementation LogManager
+ (LogManager *)shareInstance{static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{manager = [[LogManager alloc] init];if (kAllowSaveLog) {[self setDefaultUncaughtExceptionHandler];}});return manager;
}
- (void)clearAllLog {NSArray<NSString *> *allPath = [self allLogPath];if (allPath.count == 0) {return;}[allPath enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {NSError *error;[[NSFileManager defaultManager] removeItemAtPath:obj error:&error];}];
}
- (void)redirectNSlogToDocumentFolder{if (kAllowSaveLog == NO) {return;}UIDevice *device = [UIDevice currentDevice];if ([[device model] isEqualToString:@"Simulator"]) {return;}NSDateFormatter *formatter = [[NSDateFormatter alloc] init];[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];NSString *dateString = [formatter stringFromDate:[NSDate date]];NSString *documentDirectory = [self logDirPath];NSString *fileName = [NSString stringWithFormat:@"%@-log.txt",dateString];NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];// Delete existing files[[NSFileManager defaultManager] removeItemAtPath:logFilePath error:nil];//Enter the log into the file  (所有的打印都会存在该文件)freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding], "a+", stdout);freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);}- (float)sizeOfLogs{NSDirectoryEnumerator *direnum = [[NSFileManager defaultManager] enumeratorAtPath:[self logDirPath]];NSString *pname;int64_t s=0;while (pname = [direnum nextObject]){NSDictionary *currentdict=[direnum fileAttributes];NSString *filesize=[NSString stringWithFormat:@"%@",[currentdict objectForKey:NSFileSize]];NSString *filetype=[currentdict objectForKey:NSFileType];if([filetype isEqualToString:NSFileTypeDirectory]) continue;s=s+[filesize longLongValue];}return s*1.0;
}
- (NSString *)logDirPath {NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentDirectory = [paths objectAtIndex:0];NSString *logPath = [documentDirectory stringByAppendingPathComponent:@"Logs"];BOOL isDir = NO;BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:logPath isDirectory:&isDir];if (isExist && isDir) {} else {NSError * createDirError;[[NSFileManager defaultManager] createDirectoryAtPath:logPath withIntermediateDirectories:YES attributes:nil error:&createDirError];}return logPath;
}
- (NSArray<NSString *> *)allLogPath {NSArray<NSString *> *items = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self logDirPath] error:nil];NSMutableArray<NSString *> *paths = [NSMutableArray array];NSString *dirPath = [self logDirPath];[items enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {[paths addObject:[dirPath stringByAppendingPathComponent:obj]];}];return paths;
}#pragma mark -设置crash
+ (void)setDefaultUncaughtExceptionHandler
{NSSetUncaughtExceptionHandler (&chUncaughtExceptionHandler);signal(SIGABRT, SignalHandler);signal(SIGILL, SignalHandler);signal(SIGSEGV, SignalHandler);signal(SIGFPE, SignalHandler);signal(SIGBUS, SignalHandler);signal(SIGPIPE, SignalHandler);}#pragma mark -获取崩溃日志
void chUncaughtExceptionHandler(NSException *exception)
{NSLog(@"Exception info --> %@",exception);
}void SignalHandler(int signal)
{//拦截signal
}@end

分享

收集到的日志可以通过云端上传,也可以直接通过系统原生分享。

/// items 可以传文件路径path。 
+ (void)shareItems:(NSArray *)items  fromController:(UIViewController *)controller cancel:(void(^)(void))cancel completion:(void(^)(NSError * _Nullable error))completion {if (items.count == 0) {return;}//初始化:UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];activityVC.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {// 如果取消, completed返回 NOif (completed) {if (completion) {completion(activityError);}} else {if (cancel) {cancel();}}};//禁掉不用的服务activityVC.excludedActivityTypes = @[UIActivityTypePrint,UIActivityTypeAssignToContact];[controller presentViewController:activityVC animated:YES completion:nil];
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 进程程序替换
  • 亚马逊云(AWS)技术深度解析及代码使用案例
  • 华为od全面介绍!!!
  • Redis/ElaticSearch/kafka入门
  • 每日OJ_牛客_mkdir(排序+模拟)
  • android 离线的方式使用下载到本地的gradle
  • 【云原生系列之SkyWalking的部署】
  • 【QNX+Android虚拟化方案】112 - 获取 88Q5152 Switch Port1、Port2 端口的主从模式 / 传输速率 / 链路状态
  • C++系列-STL容器之list
  • C++中的异常处理与资源管理
  • 银河麒麟v10-sp3-x86系统安装k8s-1.30.4
  • 如何判断儿童是否患有自闭症
  • 数据结构--排序实现--C语言
  • uniapp解决app端不能用<web-view>将外部页面嵌入当前页面的问题
  • 如何查看在同一网段内的IP
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • css系列之关于字体的事
  •  D - 粉碎叛乱F - 其他起义
  • ERLANG 网工修炼笔记 ---- UDP
  • Facebook AccountKit 接入的坑点
  • gops —— Go 程序诊断分析工具
  • nodejs实现webservice问题总结
  • 闭包--闭包之tab栏切换(四)
  • 从0实现一个tiny react(三)生命周期
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 如何合理的规划jvm性能调优
  • 使用common-codec进行md5加密
  • 由插件封装引出的一丢丢思考
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​MySQL主从复制一致性检测
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • (02)Unity使用在线AI大模型(调用Python)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (java)关于Thread的挂起和恢复
  • (二十三)Flask之高频面试点
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (算法)求1到1亿间的质数或素数
  • (一)认识微服务
  • .NET 8.0 发布到 IIS
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET IoC 容器(三)Autofac
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET 命令行参数包含应用程序路径吗?
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET实现之(自动更新)
  • @Conditional注解详解
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [240812] X-CMD 发布 v0.4.5:更新 gtb、cd、chat、hashdir 模块功能
  • [AI 大模型] 百度 文心一言
  • [AWS]CodeCommit的创建与使用