263 lines
7.7 KiB
Objective-C
263 lines
7.7 KiB
Objective-C
//
|
||
// BuglyManager.m
|
||
// YuMi
|
||
//
|
||
// Created by BuglyManager
|
||
// Copyright © 2024 YuMi. All rights reserved.
|
||
//
|
||
|
||
#import "BuglyManager.h"
|
||
#import <Bugly/Bugly.h>
|
||
|
||
@interface BuglyManager () <BuglyDelegate>
|
||
|
||
@property (nonatomic, strong) NSString *appId;
|
||
@property (nonatomic, assign) BOOL isConfigured;
|
||
|
||
@end
|
||
|
||
@implementation BuglyManager
|
||
|
||
#pragma mark - Singleton
|
||
|
||
+ (instancetype)sharedManager {
|
||
static BuglyManager *instance = nil;
|
||
static dispatch_once_t onceToken;
|
||
dispatch_once(&onceToken, ^{
|
||
instance = [[BuglyManager alloc] init];
|
||
});
|
||
return instance;
|
||
}
|
||
|
||
- (instancetype)init {
|
||
self = [super init];
|
||
if (self) {
|
||
_isConfigured = NO;
|
||
}
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - BuglyDelegate
|
||
- (NSString * BLY_NULLABLE)attachmentForException:(NSException * BLY_NULLABLE)exception {
|
||
NSString *message = [NSString stringWithFormat:@"%@ - %@", exception.name, exception.reason];
|
||
[self handleLagDetection:message];
|
||
return message;
|
||
}
|
||
|
||
#pragma mark - Public Methods
|
||
|
||
- (void)configureWithAppId:(NSString *)appId debug:(BOOL)isDebug {
|
||
if (self.isConfigured) {
|
||
NSLog(@"[BuglyManager] Bugly 已经配置,跳过重复配置");
|
||
return;
|
||
}
|
||
|
||
if (!appId || appId.length == 0) {
|
||
NSLog(@"[BuglyManager] 错误:appId 不能为空");
|
||
return;
|
||
}
|
||
|
||
self.appId = appId;
|
||
|
||
// 创建 Bugly 配置
|
||
BuglyConfig *config = [[BuglyConfig alloc] init];
|
||
config.delegate = self;
|
||
|
||
// 基础配置
|
||
config.blockMonitorTimeout = 3.0; // 卡顿监控超时时间:3秒
|
||
config.blockMonitorEnable = YES; // 启用卡顿监控
|
||
|
||
// 调试模式配置
|
||
if (isDebug) {
|
||
config.debugMode = NO; // 生产环境关闭调试模式
|
||
config.channel = [self getAppChannel];
|
||
config.reportLogLevel = BuglyLogLevelWarn; // 设置日志级别
|
||
} else {
|
||
config.unexpectedTerminatingDetectionEnable = YES; // 非正常退出事件记录
|
||
config.debugMode = NO;
|
||
config.channel = [self getAppChannel];
|
||
config.blockMonitorEnable = YES;
|
||
config.reportLogLevel = BuglyLogLevelWarn;
|
||
}
|
||
// 启动 Bugly
|
||
[Bugly startWithAppId:appId config:config];
|
||
|
||
self.isConfigured = YES;
|
||
|
||
NSLog(@"[BuglyManager] Bugly 配置完成 - AppID: %@, Debug: %@", appId, isDebug ? @"YES" : @"NO");
|
||
}
|
||
|
||
- (void)reportError:(NSString *)domain
|
||
code:(NSInteger)code
|
||
userInfo:(NSDictionary *)userInfo {
|
||
|
||
if (!self.isConfigured) {
|
||
NSLog(@"[BuglyManager] 错误:Bugly 未配置,无法上报错误");
|
||
return;
|
||
}
|
||
|
||
if (!domain || domain.length == 0) {
|
||
domain = @"UnknownError";
|
||
}
|
||
|
||
// 创建错误对象
|
||
NSError *error = [NSError errorWithDomain:domain
|
||
code:code
|
||
userInfo:userInfo];
|
||
|
||
// 异步上报错误
|
||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||
[Bugly reportError:error];
|
||
NSLog(@"[BuglyManager] 错误上报成功 - Domain: %@, Code: %ld", domain, (long)code);
|
||
});
|
||
}
|
||
|
||
- (void)reportBusinessError:(NSString *)message
|
||
code:(NSInteger)code
|
||
context:(NSDictionary *)context {
|
||
|
||
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||
|
||
// 添加基础信息
|
||
if (message && message.length > 0) {
|
||
[userInfo setObject:message forKey:@"error_message"];
|
||
}
|
||
[userInfo setObject:@(code) forKey:@"error_code"];
|
||
[userInfo setObject:@"BusinessError" forKey:@"error_type"];
|
||
|
||
// 添加上下文信息
|
||
if (context && context.count > 0) {
|
||
[userInfo addEntriesFromDictionary:context];
|
||
}
|
||
|
||
// 添加时间戳
|
||
[userInfo setObject:@([[NSDate date] timeIntervalSince1970]) forKey:@"timestamp"];
|
||
|
||
[self reportError:@"BusinessError" code:code userInfo:userInfo];
|
||
}
|
||
|
||
- (void)reportNetworkError:(NSString *)uid
|
||
api:(NSString *)api
|
||
code:(NSInteger)code
|
||
userInfo:(NSDictionary *)userInfo {
|
||
|
||
NSMutableDictionary *errorInfo = [NSMutableDictionary dictionary];
|
||
|
||
// 添加网络错误特有信息
|
||
if (uid && uid.length > 0) {
|
||
[errorInfo setObject:uid forKey:@"user_id"];
|
||
}
|
||
if (api && api.length > 0) {
|
||
[errorInfo setObject:api forKey:@"api_path"];
|
||
}
|
||
[errorInfo setObject:@(code) forKey:@"http_code"];
|
||
[errorInfo setObject:@"NetworkError" forKey:@"error_type"];
|
||
|
||
// 添加调用栈信息
|
||
[errorInfo setObject:[NSThread callStackSymbols] forKey:@"call_stack_symbols"];
|
||
|
||
// 合并额外信息
|
||
if (userInfo && userInfo.count > 0) {
|
||
[errorInfo addEntriesFromDictionary:userInfo];
|
||
}
|
||
|
||
[self reportError:@"NetworkError" code:code userInfo:errorInfo];
|
||
}
|
||
|
||
- (void)reportIAPError:(NSString *)uid
|
||
transactionId:(NSString *)transactionId
|
||
orderId:(NSString *)orderId
|
||
status:(NSInteger)status
|
||
context:(NSDictionary *)context {
|
||
|
||
NSMutableDictionary *errorInfo = [NSMutableDictionary dictionary];
|
||
|
||
// 添加内购错误特有信息
|
||
if (uid && uid.length > 0) {
|
||
[errorInfo setObject:uid forKey:@"user_id"];
|
||
}
|
||
if (transactionId && transactionId.length > 0) {
|
||
[errorInfo setObject:transactionId forKey:@"transaction_id"];
|
||
}
|
||
if (orderId && orderId.length > 0) {
|
||
[errorInfo setObject:orderId forKey:@"order_id"];
|
||
}
|
||
[errorInfo setObject:@(status) forKey:@"status_code"];
|
||
[errorInfo setObject:@"IAPError" forKey:@"error_type"];
|
||
|
||
// 添加状态描述
|
||
NSString *statusMsg = [self getIAPStatusMessage:status];
|
||
if (statusMsg) {
|
||
[errorInfo setObject:statusMsg forKey:@"status_message"];
|
||
}
|
||
|
||
// 合并上下文信息
|
||
if (context && context.count > 0) {
|
||
[errorInfo addEntriesFromDictionary:context];
|
||
}
|
||
|
||
// 生成错误码
|
||
NSInteger errorCode = -20000 + status;
|
||
|
||
[self reportError:@"IAPError" code:errorCode userInfo:errorInfo];
|
||
}
|
||
|
||
- (void)startLagDetection {
|
||
if (!self.isConfigured) {
|
||
NSLog(@"[BuglyManager] 错误:Bugly 未配置,无法启动卡顿检测");
|
||
return;
|
||
}
|
||
|
||
NSLog(@"[BuglyManager] 手动启动卡顿检测");
|
||
// Bugly 会自动进行卡顿检测,这里主要是日志记录
|
||
}
|
||
|
||
#pragma mark - Private Methods
|
||
|
||
- (void)handleLagDetection:(NSString *)stackTrace {
|
||
NSLog(@"[BuglyManager] 🚨 检测到卡顿 - StackTrace: %@", stackTrace);
|
||
|
||
// 计算卡顿持续时间(这里假设为3秒,实际应该从 Bugly 配置中获取)
|
||
NSTimeInterval duration = 3.0;
|
||
|
||
// 通知代理
|
||
if (self.delegate && [self.delegate respondsToSelector:@selector(buglyManager:didDetectLag:)]) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[(id<BuglyManagerDelegate>)self.delegate buglyManager:self didDetectLag:duration];
|
||
});
|
||
}
|
||
|
||
// TODO: 触发卡顿通知逻辑
|
||
// 1. 记录卡顿信息到本地日志
|
||
// 2. 发送本地通知
|
||
// 3. 记录到性能监控系统
|
||
// 4. 触发用户反馈机制
|
||
}
|
||
|
||
- (NSString *)getAppChannel {
|
||
// 这里应该调用项目中的工具方法获取渠道信息
|
||
// 暂时返回默认值
|
||
return @"AppStore";
|
||
}
|
||
|
||
- (NSString *)getIAPStatusMessage:(NSInteger)status {
|
||
switch (status) {
|
||
case 0:
|
||
return @"尝试验单";
|
||
case 1:
|
||
return @"验单-补单成功";
|
||
case 2:
|
||
return @"验单-补单失败";
|
||
case 3:
|
||
return @"验单-补单 id 异常";
|
||
case 4:
|
||
return @"重试次数过多";
|
||
case 5:
|
||
return @"过期交易清理";
|
||
default:
|
||
return @"未知状态";
|
||
}
|
||
}
|
||
|
||
@end
|