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];
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/878634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【多场景应用】基于杰发科技AC7840x的Mini LED背光驱动设计

应用场景&#xff1a; 在汽车应用中&#xff0c;Mini LED背光驱动设计主要用于仪表盘、中控屏和车载娱乐系统等显示屏。这项技术可以显著提升显示效果&#xff0c;提供更高的亮度、更深的黑色和更广的色域&#xff0c;使得图像更加生动逼真&#xff0c;尤其在强光和宽温度范围…

Redis 篇-深入了解查询缓存与缓存所带来的问题(读写不一致、缓存穿透、缓存雪崩、缓存击穿)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 本章目录 1.0 什么是缓存 2.0 项目中具体如何添加缓存 3.0 添加缓存后所带来的问题 3.1 读写不一致问题 3.1.1 缓存更新策略 3.1.2 具体实现缓存与数据库的双写一致 3.2 缓存穿…

【日记】想见珍一面怎么就这么难(985 字)

正文 想见珍一面怎么就这么难…… 事故频发。昨天说考试时间跟机票时间冲突了&#xff0c;最后结果出来了&#xff0c;改签了&#xff0c;并且差价不补。我不干&#xff0c;他们也不干。因为上级行给我们行长施压&#xff0c;于是我们行长给我施压。最后要到了国庆之前拔智齿的…

詳細解析軟路由與代理爬蟲池-okeyproxy

什麼是軟路由&#xff1f; 軟路由&#xff0c;顧名思義&#xff0c;就是通過軟體實現的路由器功能。與傳統的硬體路由器不同&#xff0c;軟路由通常是基於PC或單板電腦&#xff08;如樹莓派&#xff09;運行的路由器軟體。 靈活性高&#xff1a;可以根據需求安裝各種插件和服…

华为 HCIP-Datacom H12-821 题库 (6)

有需要题库的可以看主页置顶 V群仅进行学习交流 1.转发表中 FLAG 字段中B 的含义是&#xff1f; A、可用路由 B、静态路由 C、黑洞路由 D、网关路由 答案&#xff1a;C 解析&#xff1a; 可用路由用U 表示&#xff0c;静态路由用 S 表示&#xff0c;黑洞路由用 B 表示&#x…

网站一些标识

1.网站TDK大三标签SEO优化 SEO(Search engine optimzation) 汉译为搜索引擎优化&#xff0c;是一种利用搜索引擎的规则提高网站在有关搜索引擎内自然排名的方式。 ​ SEO的目的是对网站进行深度的优化&#xff0c;从而帮助获取免费的流量&#xff0c;进而在搜索引擎上提升网站…

笔试,牛客.kotori和n皇后​,牛客.AOE还是单体

目录 牛客.kotori和n皇后​编辑 牛客.AOE还是单体 牛客.kotori和n皇后 想起来&#xff0c;我之前还写过n皇后的题&#xff0c;但是这个我开始只能想到暴力解法 判断是不是斜对角线&#xff0c;联想yxb和y-xb,假如在一条线上&#xff0c;那么他们的x和y会对应成比例&#xff0c…

【弱监督时间动作定位】Probabilistic Vision-Language Representation for WSTAL 论文阅读

Probabilistic Vision-Language Representation for Weakly Supervised Temporal Action Localization 论文阅读 Abstract1 Introduction2 RELATEDWORK2.1 Weakly Supervised Temporal Action Localization2.2 Vision Language Pre-training2.3 Probabilistic Representation 3…

RocketMQ高级特性四-消息过滤

目录 前言 Broker端过滤 定义与概述 消息过滤分类 原理机制 使用场景 优缺点 Java代码示例 - Tag过滤 Java代码示例 - SQL92过滤 客户端过滤 定义与概述 原理机制 使用场景 优缺点 Java代码示例 总结 前言 消息过滤是RocketMQ的一项高级特性&#xff0c;它允许…

常见HTTP状态码、APUD响应状态字及含义

目录 一、HTTP状态码 二、APDU指令码 一、HTTP状态码 HTTP状态&#xff08;HTTP Status Code&#xff09;是用以表示网页服务器超文本传输协议响应状态的3位数字代码。 关于HTTP状态码更加详细介绍推荐阅读&#xff1a; http://t.csdnimg.cn/qSJv6http://t.csdnimg.cn/qSJv…

光敏电阻传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.光敏电阻传感器介绍 2.原理图 三、程序设计 main.c文件 ldr.h文件 ldr.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 光敏电阻器是利用半导体的光电导效应制成的一种电阻值随入射光的强弱而改变的电阻器&#xff0c;又称为光…

基于树莓派的儿童音频播发器—Yoto

Raspberry Pi 的开发可能性使吸引人的、以儿童为中心的音频播放器得以成型 Yoto Player 为孩子们提供了拥有和控制的绝佳体验&#xff0c;同时不会增加屏幕时间。得益于 Raspberry Pi 以及我们认可的经销商提供的支持和专业知识&#xff0c;Yoto Player 在英国取得了成功。 Yo…

streamlit示例-极简

登录注册多步骤任务和实时展示结果 封装后的 Streamlit 示例代码 访问演示地址 import streamlit as st import time# In-memory "database" for simplicity users_db {admin: {password: admin123, name: Admin, age: 30, favorite_color: blue} }def register_…

(C++ STL)list类的简单模拟实现与源码展示

list类的简单模拟实现 一、前言二、ListNode 单个节点的成员变量三、ListIterator 迭代器四、ReverseListIterator 迭代器五、list 的成员变量与初始化六、list 部分函数实现inserterase 七、list 源代码 以下代码环境为 VS2022 C。 一、前言 list类 本质上是数据结构中的双向…

JVM GC 调优

文章目录 引言I 调整JVM的默认堆内存配置1.1 java命令启动jar包时配置JVM 的内存参数1.2 基于Tomcat服务器部署的java应用,配置JVM 的内存参数II JVM GC 调优基本概念: 应用程序的响应时间(RT)和吞吐量(QPS)JVM调优原理调优思路调优方法JVM调优技巧建议引言 内存参数:ht…

七款最佳的渗透测试工具(非常详细)零基础入门到精通,收藏这一篇就够了

渗透测试工具是模拟对计算机系统、网络或 Web 应用程序的网络攻击的软件应用程序&#xff0c;它们的作用是在实际攻击者之前发现安全漏洞。它们可以作为系统的压力测试&#xff0c;揭示哪些区域可能会受到真正的威胁。 本文我将介绍七款最佳的渗透测试工具。 1 Kali Linux K…

Maven入门:自动化构建工具的基本概念与配置

一、什么是Maven 目前无论使用IDEA还是Eclipse等其他IDE&#xff0c;使用里面 ANT 工具帮助我们进行编译&#xff0c;打包运行等工作。Apache基于ANT进行了升级&#xff0c;研发出了全新的自动化构建工具Maven。 Maven使用项目对象模型&#xff08;POM-Project Object Model&…

视频合并在线工具哪个好?好用的视频合并工具推荐

当我们手握一堆零散却各有千秋的视频片段时&#xff0c;是否曾幻想过它们能像魔法般合并成一部完整、流畅的故事&#xff1f; 别担心&#xff0c;今天咱们就来一场“视频合并大冒险”&#xff0c;揭秘几款视频合并软件手机免费工具&#xff0c;帮助你在指尖上实现创意无限的视…

四、配置三层交换实验组网

一、实验拓扑 二、实验目的 通过配置交换机&#xff0c;令不同vlan间的主机能够互相通信 三、实验步骤 SW12 <Huawei>undo terminal monitor Info: Current terminal monitor is off. <Huawei>system-view Enter system view, return user view with CtrlZ. [H…

3、DjangoAdmin导出excel和csv文件

一、导出Excel 1、安装openpyxl库 2、admin文件 # 导入openpyxl库中的Workbook类&#xff0c;用于创建Excel文件 from openpyxl import Workbook # 导入Django的admin模块&#xff0c;用于在Django admin后台注册和管理模型 from django.contrib import admin # 导入…