iOS集成Bugly详解

2023-11-12

异常上报

SDK 集成

  • 通过CocoaPods集成

新建项目

cd 项目目录
vim Podfile

#

source 'https://github.com/CocoaPods/Specs.git'

inhibit_all_warnings!

platform :ios, '7.0'

target 'BuglyDemo' do
pod 'ReactiveCocoa','2.5'
pod 'AFNetworking', '2.5.4'
pod 'MJExtension', '2.0.4'
pod 'MJRefresh','3.1.9'
pod 'SDWebImage','3.7.5'
pod 'UITableView+FDTemplateLayoutCell'
pod 'Bugly'
end

保存并执行pod install,然后用后缀为.xcworkspace的文件打开工程。

初始化SDK

导入头文件

在工程的AppDelegate.m文件导入头文件

 #import <Bugly/Bugly.h>
 //如果是Swift工程,请在对应bridging-header.h中导入

默认Debug模式,是不会生成dSYM文件,需要开启.重新编译CMD+B,修改配置如下图

这里写图片描述

Bugly后台显示异常数据

这里写图片描述

dSYM文件
iOS平台中,dSYM文件是指具有调试信息的目标文件,文件名通常为:xxx.app.dSYM。

  • 为了方便找回Crash对应的dSYM文件和还原堆栈,建议每次构建或者发布APP版本的时候,备份好dSYM文件。

这里写图片描述

生成后,在哪里可以找到dSYM文件?

这里写图片描述

这里写图片描述

这里写图片描述

保存log到本地,并上传到Bugly管理后台

1.遵守代理协议

@interface AppDelegate ()<BuglyDelegate>

2.设置代理对象

 BuglyConfig *config = [[BuglyConfig alloc] init];
 config.delegate = self;
 [Bugly startWithAppId:@"你的AppId" config:config];

3.实现代理方法attachmentForException

#pragma mark - Bugly代理 - 捕获异常,回调(@return 返回需上报记录,随 异常上报一起上报)
- (NSString *)attachmentForException:(NSException *)exception {

    #ifdef DEBUG // 调试
    return [NSString stringWithFormat:@"我是携带信息:%@",[self redirectNSLogToDocumentFolder]];
    #endif

    return nil;
}

#pragma mark - 保存日志文件
- (NSString *)redirectNSLogToDocumentFolder{
    //如果已经连接Xcode调试则不输出到文件
    if(isatty(STDOUT_FILENO)) {
        return nil;
    }
    UIDevice *device = [UIDevice currentDevice];
    if([[device model] hasSuffix:@"Simulator"]){
        //在模拟器不保存到文件中
        return nil;
    }
    //获取Document目录下的Log文件夹,若没有则新建
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Log"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL fileExists = [fileManager fileExistsAtPath:logDirectory];
    if (!fileExists) {
        [fileManager createDirectoryAtPath:logDirectory  withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; //每次启动后都保存一个新的日志文件中
    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
    NSString *logFilePath = [logDirectory stringByAppendingFormat:@"/%@.txt",dateStr];
    // freopen 重定向输出输出流,将log输入到文件
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);

    return [[NSString alloc] initWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];

}

Bugly iOS 符号表配置

什么是符号表?

符号表是内存地址与函数名、文件名、行号的映射表。符号表元素如下所示:

<起始地址> <结束地址> <函数> [<文件名:行号>]

为什么要配置符号表?
为了能快速并准确地定位用户APP发生Crash的代码位置,Bugly使用符号表对APP发生Crash的程序堆栈进行解析和还原。

自动配置:XCode + sh脚本

这里写图片描述

到官方文档下载自动配置符号表工具包,解压如下:

这里写图片描述

使用文档中的方式一进行配置(默认方式)

配置Xcode编译执行脚本

  • 在Xcode工程对应Target的Build Phases中新增Run Scrpit Phase

这里写图片描述

打开工具包中的dSYM_upload.sh,复制所有内容,在新增的Run Scrpit Phase中粘贴

这里写图片描述

修改新增的Run Scrpit中的 <YOUR_APP_ID> 为您的App ID<YOUR_APP_KEY>为您的App Key<YOUR_BUNDLE_ID> 为App的Bundle Id

这里写图片描述

脚本默认在Debug模式及模拟器编译情况下不会上传符号表,在需要上传的时候,请修改下列选项

  • Debug模式编译是否上传,1=上传 0=不上传,默认不上传
UPLOAD_DEBUG_SYMBOLS=0
  • 模拟器编译是否上传,1=上传 0=不上传,默认不上传
UPLOAD_SIMULATOR_SYMBOLS=0

至此,自动上传符号表脚本配置完毕,Bugly 会在每次 Xcode 工程编译后自动完成符号表配置工作。

应用升级&热更新

介绍:
Bugly 应用升级服务为您的应用版本配置升级提醒,并可对用户范围及数量进行精准控制,多纬度数据监控,实时了解版本转化率。

不过看文档介绍没有iOS端的应用升级。

注意Bugly使用的是JSpatch来做热更新的,可能导致上线审核时被拒绝。

因为苹果公司对热更新的强烈抵制,所以Bugly才把异常上报功能和热更新的SDK分开集成。

所以有迫切迭代上线应用的小伙伴慎用!!!
所以有迫切迭代上线应用的小伙伴慎用!!!
所以有迫切迭代上线应用的小伙伴慎用!!!

因为BuglyHotfix SDK v2.0 及以上版本不包含 JSPatch,所以JSPatch要单独集成
这里写图片描述

SDK 集成

pod 'BuglyHotfix'
  • 注意点

BuglyHotfix iOS SDK 最低兼容 iOS 系统版本 iOS 7.0
BuglyHotfix 已经包含 Bugly 的所有功能,如果已经集成 Bugly SDK,请移除 Bugly 并替换成 BuglyHotfix 。

JSPatch 集成

JSPatch下载
把下列文件拖入 Xcode 工程内(请勾选Copy items if needed选项)

JPEngine.h
JPEngine.m
JSPatch.js

在工程内的Prefix Header(后缀为.pch)的文件内 #include “BuglyHotfixConfuse_pch.h” ,如工程内没有 pch 文件请参见这篇文章配置。

初始化SDK

#import "AppDelegate.h"
#import <BuglyHotfix/Bugly.h>
#import <BuglyHotfix/BuglyMender.h>
#import "JPEngine.h"

@interface AppDelegate ()<BuglyDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self configBugly];
    return YES;
}
- (void)configBugly {
    //初始化 Bugly 异常上报
    BuglyConfig *config = [[BuglyConfig alloc] init];
    config.delegate = self;
    config.debugMode = YES;
    config.reportLogLevel = BuglyLogLevelInfo;
    [Bugly startWithAppId:@"b950788e02"
#if DEBUG
        developmentDevice:YES
#endif
                   config:config];

    //捕获 JSPatch 异常并上报
    [JPEngine handleException:^(NSString *msg) {
        NSException *jspatchException = [NSException exceptionWithName:@"Hotfix Exception" reason:msg userInfo:nil];
        [Bugly reportException:jspatchException];
    }];
    //检测补丁策略
    [[BuglyMender sharedMender] checkRemoteConfigWithEventHandler:^(BuglyHotfixEvent event, NSDictionary *patchInfo) {
        //有新补丁或本地补丁状态正常
        if (event == BuglyHotfixEventPatchValid || event == BuglyHotfixEventNewPatch) {
            //获取本地补丁路径
            NSString *patchDirectory = [[BuglyMender sharedMender] patchDirectory];
            if (patchDirectory) {
                //指定执行的 js 脚本文件名
                NSString *patchFileName = @"main.js";
                NSString *patchFile = [patchDirectory stringByAppendingPathComponent:patchFileName];
                //执行补丁加载并上报激活状态
                if ([[NSFileManager defaultManager] fileExistsAtPath:patchFile] &&
                    [JPEngine evaluateScriptWithPath:patchFile] != nil) {
                    BLYLogInfo(@"evaluateScript success");
                    [[BuglyMender sharedMender] reportPatchStatus:BuglyHotfixPatchStatusActiveSucess];
                }else {
                    BLYLogInfo(@"evaluateScript failed");
                    [[BuglyMender sharedMender] reportPatchStatus:BuglyHotfixPatchStatusActiveFail];
                }
            }
        }
    }];
}
#pragma mark - Bugly代理 - 捕获异常,回调(@return 返回需上报记录,随 异常上报一起上报)
- (NSString *)attachmentForException:(NSException *)exception {

#ifdef DEBUG // 调试
    return [NSString stringWithFormat:@"我是携带信息:%@",[self redirectNSLogToDocumentFolder]];
#endif

    return nil;
}

#pragma mark - 保存日志文件
- (NSString *)redirectNSLogToDocumentFolder{
    //如果已经连接Xcode调试则不输出到文件
    if(isatty(STDOUT_FILENO)) {
        return nil;
    }
    UIDevice *device = [UIDevice currentDevice];
    if([[device model] hasSuffix:@"Simulator"]){
        //在模拟器不保存到文件中
        return nil;
    }
    //获取Document目录下的Log文件夹,若没有则新建
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *logDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Log"];
    NSLog(@"%@",paths);
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL fileExists = [fileManager fileExistsAtPath:logDirectory];
    if (!fileExists) {
        [fileManager createDirectoryAtPath:logDirectory  withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; //每次启动后都保存一个新的日志文件中
    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
    NSString *logFilePath = [logDirectory stringByAppendingFormat:@"/%@.txt",dateStr];
    // freopen 重定向输出输出流,将log输入到文件
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stdout);
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);

    return [[NSString alloc] initWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS集成Bugly详解 的相关文章

  • iOS 外部附件框架:如何获取特定 MFI 设备的协议字符串

    我正在编写一个 iOS 应用程序 用于与 mini mPlay Drumi MP18B 小型蓝牙扬声器 进行通信 据我所知 showBluetoothAccessoryPickerWithNameFilter仅显示协议字符串添加到 Info
  • WebGL iOS 渲染为浮点纹理

    我正在尝试在 iOS Safari 上的 WebGL 中渲染浮点纹理 而不是在本机应用程序中 我已经设法让 iOS 读取手动 例如从 JavaScript 创建的浮点纹理 但是当我创建浮点类型的帧缓冲区并使用 GPU 渲染到其中时 它不起作
  • iOS 内存警告

    我正在尝试使用从 Parse 数据库下载的图像填充集合视图 但我收到内存警告 然后偶尔崩溃 有谁知道其他应用程序如何设法呈现这么多图像而不崩溃 有人可以告诉我如何优化我已有的东西吗 这是所有相关代码 https gist github co
  • 更改 UITextField 辅助功能描述

    有没有办法将 UITextField 的辅助功能标签设置为 文本字段 之外的其他内容 因此 我不想将其称为 文本字段 而是将其命名为 代码验证字段 我的建议是不要试图在内置语音输出上智取系统 对于盲人用户来说 文本字段正在编辑 相当于 该项
  • swift 中的负数模

    负数模如何在 swift 中工作 当我执行 1 3 时 它给出 1 但余数是 2 其中有什么问题 雨燕余数运算符 计算余数 整数除法 a b a a b b where 是截断整数除法 在你的情况下 1 3 1 1 3 3 1 0 3 1
  • 如何使用自签名证书为 TLS 创建 iOS NWConnection?

    我正在尝试将 Apple 的新 NWConnection 类用于我的 MQTT 客户端 为了进行测试 我需要能够创建到本地测试代理的 TLS 连接 该代理具有自签名证书 到目前为止 我只是使用以下命令设置连接 self connection
  • 在WKWebview中设置useragent

    如何在 WKWebView 中设置自定义用户代理字符串 我正在尝试嵌入我的应用程序的版本 以便我的服务器端可以看到可用的功能 我找到了以下方法 let userAgent MyApp 1 33 7 request setValue user
  • 播放(非库)Apple Music 内容 - 请求失败

    我正在尝试使用以下代码播放专辑 let predicate MPMediaPropertyPredicate value 1459938538 forProperty MPMediaItemPropertyAlbumPersistentID
  • 在两个数字之间设置 UILabel 文本动画?

    我是 iPhone 和 Mac 编程新手 之前为 Windows 开发过 我有一个问题 我如何制作动画text的财产UILabel两个数字之间 例如从5 to 80以 Ease Out 风格 是否可以与CoreAnimation 我已经在谷
  • Xcode 9.0.1 应用程序分发程序已更改

    最近我将 Xcode 升级到了 Xcode 9 1 之后 当我尝试发布我的应用程序时 Xcode 不允许选择我为临时创建的分发配置文件 这么说 配置文件不是 IOS 应用商店配置文件 如果 Xcode 9 1 的应用程序分发过程有变化 请告
  • ObjC <-> Swift 桥接和工厂方法

    我想从 Swift 使用一些 Objective C 类 由于超出了这个问题范围的原因 我的班级init方法被标记为不可用 相反 有一个工厂方法 这是我的班级的简化形式 interface MyClass NSObject instance
  • 删除部分(红色删除按钮),UITableViewController - iOS

    我正在尝试做一个分组的 uitableview 并且我已经激活了编辑选项 我希望用户也能够删除整个部分 而不仅仅是特定行 因此 当您单击 编辑 时 每个表格单元格左侧显示的红色减号按钮也应该显示在各个部分 部分标题左侧 有人知道如何做到这一
  • 使用原始类型+大小写参数的 Swift Enum 的解决方法?

    我想创建 SKSpriteNodesWallType 请参阅下面的代码 并且仅当WallType is Corner通过它Side其方向的价值 枚举具有原始值 因为我需要将它们作为数字从 plist 加载 并能够随机创建它们 enum Si
  • 将第 3 方库添加到 iPhone 应用程序时如何设置“标题搜索路径”的路径

    我想添加第 3 方库语音转文本 https github com todoroo iPhone Speech To Textto my Xcode项目 我只是拖xcodeproj文件在我的 iPhone 项目中 然后我按照目标依赖项 将二进
  • Firebase Messaging FCM 在可配置的时间间隔内分发

    当您使用 FCM 向给定应用程序的所有设备发送推送时 这可能会导致许多用户同时打开他们的应用程序 从而导致大量服务器轮询 从而导致负载峰值 有没有一种方便的方法可以在给定的时间间隔内分发消息以进行计划推送 最后 我们找到了一种可能的方法 通
  • AVAssetExportSession 输出文件

    AVAssetExportSession 输出文件应该是什么样子 我正在尝试压缩 ALAsset 项目中的视频 但它不起作用 我猜输出文件与它有关 这是我正在使用的代码 NSString destinationPath NSHomeDire
  • 使用排序函数按 NSDates 对数组进行排序[重复]

    这个问题在这里已经有答案了 我有一个名为的模型类Event import Foundation import MapKit public class Event let id Int var title String let status
  • iOS SDK:MapKit MKPolyLine 未显示

    我试图在地图上显示多段线 但该线没有显示 我尝试了很多事情 但注意到似乎有用 我检查了核心数据函数 它正在返回数据 所以这不是问题 它必须是我在地图点创建或地图上绘制的某个地方 我猜 我确信一定是某个地方出了点小错误 但我找不到它 My c
  • 如何在 iOS 5 中使用 Embed Segue?

    iOS 6 引入了 Embed Segue 允许在 Storyboard 中使用自定义容器控制器 有没有办法在 iOS 5 上复制这个 这里的挑战是子视图控制器的视图通常要添加为父视图控制器的某些容器视图的子视图 因为你不能随机进行序列UI
  • iOS SWIFT - WebRTC 从前置摄像头更改为后置摄像头

    WebRTC 视频默认使用前置摄像头 效果很好 但是 我需要将其切换到后置摄像头 但我无法找到任何代码来执行此操作 我需要编辑哪一部分 是 localView 或 localVideoTrack 还是捕获器 斯威夫特3 0 对等连接只能有一

随机推荐

  • sql: SQLite,MySQL,SQL Server

    SQLite 3 CREATE TABLE DuStudentList StudentId INTEGER PRIMARY KEY AUTOINCREMENT StudentName TEXT NOT NULL StudentNO TEXT
  • Oracle 11Gr1监听报错TNS-12542 12560 00512

    环境 Oracle 11Gr1 Linux Redhat 5 重启机器后 数据库监听启动报错如下 TNS 12542 TNS address already in use TNS 12560 TNS protocol adapter err
  • Go_数据类型转换(Sprintf、Format)

    数据类型转换 类型转换是将一种数据类型的变量转为另一种类型的变量 Go强制要求使用显式类型转换 所以语法更能确定语句及表达式的明确含义 转换的时候如果大的转给小的 会有精度损失 数据溢出 比如int64转int8 转换格式 将v转成T类型
  • vscode php debug断点调试

    记录一个我配置debug的总结 大概步骤 下载对应版本xdebug 下载vscode插件 配置 只要跟着一步一步配置即可 在桌面创建一个test文件夹 创建一个index php文件 win r 输出cmd cd到这个文件夹 使用php内置
  • 这一年,我们一起追过的梦想

    这一年 我们一起追过的梦想 梦想是一个好大的话题 是一个振奋人心的词汇 也是一个遥遥无期的词汇 总是给人希望 但是却让人很难把握 这一年我们牢牢的把握住了时间 让它发挥它最大的效益 IT主旋律 键盘上的舞动 这个学期开始接触软件工程项目之C
  • 2013-2014嵌入式开发从业人员调查报告

    调查背景 在嵌入式 移动互联网 物联网等热门技术日益普及的今天 以实现智能化为核心目标的典型技术 已经成为了整个信息产业毋庸置疑的主旋律 特别是近1年 以智能家居 智能医疗 可穿戴设备等为首的大量智能硬件批量的进入到人们的生活 更让这一场智
  • 学习太极创客 — MQTT(七)MQTT 主题进阶

    视频链接 https www bilibili com video BV1Va4y1W7Ub spm id from autoNext vd source b91967c499b23106586d7aa35af46413 资料链接 http
  • 来袭!SOLIDWORKS 2024 主要增强功能

    在SOLIDWORKS软件使用过程中 我们知道您创建了出色的设计 您的出色设计也会得到构建 为了简化和加快从概念到制造产品的产品开发流程 SOLIDWORKS 2024 包含用户驱动的全新增强功能 重点关注 提高工作智能化程度 通过更有效地
  • 软件测试及自动化测试

    软件测试面经 文章目录 软件测试面经 软件测试理论 1 GET和POST请求区别 2 web service的接口如何测试 3 cookie session与Token的区别 4 接口测试该怎么测 5 postman和jemter的区别 6
  • java 151建议_JAVA开发中151个建议

    1 不在常量和变量中出现混淆的字母 2 莫让常量蜕变成变量 3 三元操作符的类型必须一致 4 避免带有变长参数的方法重载 5 别让null值和空值威胁到变长方法 KISS原装 Keep It simple stupid即懒人原装 6 覆写变
  • 6.4集合类

    1 什么是集合 将多个对象合在一起变成一个统一的对象 然后通过这个统一的对象来实现对多个对象的管理 存储 检索 操作 传输数据 在数组里要进行这样的操作 可以会写很多算法 但在集合里 只需要调用其中的方法就可以了 集合也可以对其中的元素进行
  • 【java】Java -jar 运行的程序如何 本地代码远程调试服务器程序

    1 概述 因为要在服务器上进行es远程认证 需要先写个包进行测试一下 需要远程调用 那么改怎么做呢 远程服务命令配置 在服务器启动java jar包的命令中添加 Xdebug Xrunjdwp transport dt socket ser
  • 1033 旧键盘打字 (20分)

    这道题很坑的一点就是 有可能坏掉的键盘是空串 所有的键都是好的 如下测试用例 input NULL abcdefg output abcdefg 所以 用字符串数组的不能直接用scanf s str 读入 用string的也不能直接用cin
  • 计算机提示xinput1_3.dll丢失的三个解决方法?哪个更好用

    在遇到xinput1 3 dll丢失的问题后 我不得不花费一些时间和精力来尝试修复这个错误 这个问题导致我无法正常运行一些游戏或应用程序 给我的计算机使用带来了一些不便 问题描述 在使用计算机过程中 您可能会遇到一个错误提示 指示xinpu
  • sentinel 官方文档_Sentinel 限流与熔断初探(技巧篇)

    温馨提示 源码分析 Alibaba Sentinel 专栏开始连载 本文展示如何学习一个全新的技术的方法 该专栏基于 1 7 0 版本 在学习一个新技术或新框架时 建议先查看其官方文档以获得对其形成一个整体的认识 https github
  • 第十四章 netlink机制--基于Linux3.10

    Netlink基于网络的消息机制 能够让用户和内核空间进行通信 12 3节提到的ifconfig是使用ioctl方法和内核通信的 而ip命令则是使用netlink和内核通信的 该机制初衷是为网络服务的 但是现在起应用范围已经大大扩展 14
  • 转型IT之路七大部分从0到1全方位探秘:非科班出身如何顺利进入IT领域

    目录 了解IT领域的多样性和趋势 探索IT领域的不同方向和专业 分析市场需求和趋势 技术栈的基本概念和术语 自我评估和制定职业规划 确定个人兴趣和目标 分析现有技能和经验 设定合理的转型时间表和目标 寻求专业意见和建议 制定灵活的计划 培养
  • LaTeX页眉页脚自定义【有图有代码】

    LaTeX页眉页脚自定义 有图有代码 一 自定义页眉页脚示例 双页文档 fancyhead fancyfoot 1 代码讲解 2 自定义代码 3 页眉和页脚的装饰线 4 总页数 二 自定义页眉页脚示例 单页文档 rhead rfoot 三
  • “学习方法”学习笔记(一)费曼技巧

    以下为引用部分 作者 pimgeek 链接 https www zhihu com question 20576786 answer 21770899 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 特别说明
  • iOS集成Bugly详解

    异常上报 SDK 集成 通过CocoaPods集成 新建项目 cd 项目目录 vim Podfile source https github com CocoaPods Specs git inhibit all warnings plat