app上线之后,如何收集用户的各种闪退等问题,可以使用Bugly
Bugly创建应用
底部的参考文章有保姆级的操作介绍,这里不做赘述了。cocoapods集成
可以参考官方的 Bugly iOS SDK 使用指南,pod集成非常的简便。
pod 'Bugly'
保存并执行pod install
,然后用后缀为.xcworkspace的文件打开工程
3.项目中接入
可以封装一个类来专门处理bug相关的所有问题,参考Demo
如果想快速使用,也可以这样简单配置
4.发布的时同步上传符号表(手动、自动两种方式)
4.1首先什么是符号:内存地址与函数名、文件名、行号的映射表。
符号表元素如下所示:<起始地址> <结束地址> <函数> [<文件名:行号>]
为了能快速并准确地定位用户APP发生Crash的代码位置,Bugly使用符号表对APP发生Crash的程序堆栈进行解析和还原。
简单的说,就是将看不懂的日志信息,转换为项目中对应的类和方法,方便定位到问题所在的位置。
4.2 符号表手动上传到bugly后台
Bugly iOS 符号表配置这个文章详细讲解了如何获取符号表的几种方法。
上传符号表有手动和自动两种方式,我实践的是手动的方式,首先从工具中下载 符号表工具到本地。
最后cd到下载的工具目录下,终端执行下面的命令就好了(必须是java 1.8的环境)
java -jar buglyqq-upload-symbol.jar -appid d####d -appkey 4####-###-412b-###c3 -bundleid com.###.### -version 2.0.1 -platform IOS -inputSymbol ###.app.dSYM
看到最后的200就表示上传成功了,直接去bugly后台查看具体的报错就好了
4.3符号表自动上传到bugly后台
!/bin/sh
Copyright 2016 Bugly, Tencent. All rights reserved.
V1.4.0
2016.08.03
######################################################
1. 脚本集成到Xcode工程的Target
######################################################
--- Copy the SCRIPT to the Run Script of Build Phases in the Xcode project ---
BUGLY_APP_ID="d87e345d2d"
BUGLY_APP_KEY="46abf9ba-fc79-412b-89de-b92c26d02bc3"
BUNDLE_IDENTIFIER="com.botella.app"
UPLOAD_DSYM_ONLY=1
# 脚本默认配置的版本格式为CFBundleShortVersionString(CFBundleVersion), 如果你修改默认的版本格式, 请设置此变量, 如果不想修改, 请忽略此设置
CUSTOMIZED_APP_VERSION=""
# Debug模式编译是否上传,1=上传 0=不上传,默认不上传
UPLOAD_DEBUG_SYMBOLS=0
# 模拟器编译是否上传,1=上传 0=不上传,默认不上传
UPLOAD_SIMULATOR_SYMBOLS=0
#只有Archive操作时上传, 1=支持Archive上传 0=所有Release模式编译都上传
UPLOAD_ARCHIVE_ONLY=0
source dSYMUpload.sh
--- END OF SCRIPT ---
#######################################################
2. 脚本根据输入参数处理
#######################################################
#命令行下输入应用基本信息, .dSYM文件的父目录路径, 输出文件目录即可
sh dSYMUpload.sh <bugly_app_id> <bugly_app_key> <app_bundle_identifier> <app_version> <dSYM_src_dir> <bSYMBOL_dest_dir>
#注意:
# 1. dSYMUpload.sh会调用buglySymboliOS.jar进行.dSYM解析,所以依赖Java运行时环境
# 2. dSYMUpload.sh和buglySymboliOS.jar的文件路径需一致
--- CONTENT OF SCRIPT ---
Bugly服务域名
BUGLY_DSYM_UPLOAD_DOMAIN="api.bugly.qq.com"
注意jar工具的路径跟dSYMUpload.sh脚本路径一致, 请务必保证jar路径的正确性
BUGLY_SYMBOL_JAR_PATH="dsymtool/buglySymboliOS.jar"
查找添加到系统目录的jar工具
if [ ! -f "HOME/bin/buglySymboliOS.jar"
fi打印错误信息
function exitWithMessage(){
echo "--------------------------------"
echo "{2}
}上传bSYMBOL文件
function dSYMUpload() {
P_APP_ID="2"
P_APP_BUNDLE_ID="4"
P_BSYMBOL_ZIP_FILE="$5"P_BSYMBOL_ZIP_FILE_NAME={P_BSYMBOL_ZIP_FILE_NAME//&/_}
P_BSYMBOL_ZIP_FILE_NAME="{BUGLY_DSYM_UPLOAD_DOMAIN}/openapi/file/upload/symbol?app_id={P_APP_KEY}"
echo "dSYM upload url: (/usr/bin/curl -k "{P_APP_ID}" --form "app_key={BUNDLE_IDENTIFIER}" --form "productVersion={P_BSYMBOL_ZIP_FILE_NAME}" --form "file=@{STATUS}"
if [ ! "{STATUS}" == "{"reponseCode":"0"}" ]]; then
echo "Success to upload the dSYM for the app [{BUGLY_APP_VERSION}]"
UPLOAD_RESULT="SUCCESS"
else
echo "Error: Failed to upload the zip archive file to Bugly."
fiRemove temp dSYM archive
echo "Remove temporary zip archive: ${DSYM_ZIP_FPATH}"
/bin/rm -f "${DSYM_ZIP_FPATH}"
if [ "$?" -ne 0 ]; then
exitWithMessage "Error: Failed to remove temporary zip archive." 0
fiecho "--------------------------------"
echo "${UPLOAD_RESULT} - dSYM upload complete."if [[ "${UPLOAD_RESULT}" == "FAILTURE" ]]; then
echo "--------------------------------"
echo "Failed to upload the dSYM"
echo "Please check the script and try it again."
fi
}.dSYM解析为bSYMBOL文件
function dSYMParse() {
DSYM_FILE="2"
echo "--------------------------------"
echo "Extract symbol info from .dSYM file. to {BUGLY_SYMBOL_JAR_PATH}" -i "{DSYM_SYMBOL_FILE}" ) || exitWithMessage "Error: Failed to extract symbols." 1
echo "--------------------------------"}
执行
function run() {
CONFIG_BUGLY_APP_ID="2"
CONFIG_BUGLY_APP_BUNDLE_IDENTIFIER="4"
CONFIG_DSYM_SOURCE_DIR="6"
CONFIG_UPLOAD_DSYM_ONLY="$7"检查必须参数是否设置
if [ ! "{CONFIG_BUGLY_APP_ID}" == "App ID" ]]; then
exitWithMessage "Error: Bugly App ID not defined." 0
fi
if [ ! "{CONFIG_BUGLY_APP_BUNDLE_IDENTIFIER}" ]; then
exitWithMessage "Error: Bundle Identifier not defined." 0
fiif [ ! "${CONFIG_BUGLY_APP_VERSION}" ]; then
exitWithMessage "Error: App Version not defined." 0
fiif [ ! -e "{CONFIG_DSYM_SOURCE_DIR}" 0
fiif [ ! "{CONFIG_DSYM_DEST_DIR}" 0
fiif [ ! -e "{CONFIG_DSYM_DEST_DIR}
fiDSYM_FOLDER="'\n'
echo "Scaning dSYM FOLDER: ${DSYM_FOLDER} ..."
RET="F"for dsymFile in DSYM_FOLDER" -name '*.dSYM'); do
RET="T"
echo "Found dSYM file: $dsymFile"DSYM_FILE_NAME=${dsymFile##*/} DSYM_SYMBOL_ZIP_FILE_NAME="${DSYM_FILE_NAME}.zip" DSYM_SYMBOL_ZIP_FILE_NAME="${DSYM_SYMBOL_ZIP_FILE_NAME// /_}" DSYM_SYMBOL_ZIP_FILE=${CONFIG_DSYM_DEST_DIR}/${DSYM_SYMBOL_ZIP_FILE_NAME} if [ $CONFIG_UPLOAD_DSYM_ONLY -eq 1 ]; then if [ -e $DSYM_SYMBOL_ZIP_FILE ]; then rm -f $DSYM_SYMBOL_ZIP_FILE fi # 如果只上传dSYM,直接压缩dSYM目录 zip -r -j $DSYM_SYMBOL_ZIP_FILE $dsymFile -x *.plist else # 使用符号表工具来生成Symbol文件 dSYMParse $dsymFile $DSYM_SYMBOL_ZIP_FILE fi # 上传 dSYMUpload $CONFIG_BUGLY_APP_ID $CONFIG_BUGLY_APP_KEY $CONFIG_BUGLY_APP_BUNDLE_IDENTIFIER $CONFIG_BUGLY_APP_VERSION $DSYM_SYMBOL_ZIP_FILE
done
if [ {DSYM_FOLDER}" 0
fi
}在Xcode工程中执行
function runInXcode(){
echo "Uploading dSYM to Bugly in Xcode ..."echo "Info.Plist : ${INFOPLIST_FILE}"
BUNDLE_VERSION={INFOPLIST_FILE}")
BUNDLE_SHORT_VERSION={INFOPLIST_FILE}")组装Bugly默认识别的版本信息(格式为CFBundleShortVersionString(CFBundleVersion), 例如: 1.0(1))
if [ ! "{BUNDLE_SHORT_VERSION}({CUSTOMIZED_APP_VERSION}"
fiecho "--------------------------------"
echo "Prepare application information."
echo "--------------------------------"echo "Product Name: {BUNDLE_IDENTIFIER}"
echo "Version: {BUNDLE_VERSION}"echo "Bugly App ID: {BUGLY_APP_KEY}"
echo "Bugly App Version: ${BUGLY_APP_VERSION}"echo "--------------------------------"
echo "Check the arguments ..."检查模拟器编译是否允许上传符号
if [ "UPLOAD_SIMULATOR_SYMBOLS -eq 0 ]; then
exitWithMessage "Warning: Build for simulator and skipping to upload. \nYou can modify 'UPLOAD_SIMULATOR_SYMBOLS' to 1 in the script." 0
fi
fi检查是否是Release模式编译
if [ "UPLOAD_DEBUG_SYMBOLS -eq 0 ]; then
exitWithMessage "Warning: Build for debug mode and skipping to upload. \nYou can modify 'UPLOAD_DEBUG_SYMBOLS' to 1 in the script." 0
fi
fi检查是否Archive操作
if [ TARGET_BUILD_DIR" == "/Archive" ]]; then
echo "Archive the package"
else
exitWithMessage "Warning: Build for NOT Archive mode and skipping to upload. \nYou can modify 'UPLOAD_ARCHIVE_ONLY' to 0 in the script." 0
fi
firun {BUGLY_APP_KEY} {BUGLY_APP_VERSION} {BUILD_DIR}/BuglySymbolTemp ${UPLOAD_DSYM_ONLY}
}根据Xcode的环境变量判断是否处于Xcode环境
INFO_PLIST_FILE="${INFOPLIST_FILE}"
BuildInXcode="F"
if [ -f "${INFO_PLIST_FILE}" ]; then
BuildInXcode="T"
fiif [ $BuildInXcode = "T" ]; then
runInXcode
else
echo "\nUsage: dSYMUpload.sh <bugly_app_id> <bugly_app_key> <app_bundle_identifier> <app_version> <dSYM_src_dir> <bSYMBOL_dest_dir> [upload_dsym_only]\n"你可以在此处直接设置BuglyAppID和BuglyAppKey,排除不常变参数的输入
BUGLY_APP_ID="2"
BUNDLE_IDENTIFIER="4"
DWARF_DSYM_FOLDER_PATH="6"
UPLOAD_DSYM_ONLY={BUGLY_APP_ID} {BUNDLE_IDENTIFIER} {DWARF_DSYM_FOLDER_PATH} {UPLOAD_DSYM_ONLY}
fi
将以上内容,换上自己项目的 appid appkey bundleId后,复制到xcode中就好了。
5.Bugly查看bug详情、修复
修复好发布新版本、并同步上传新的符号表
iOS接入demo参考,基本上流程就是在官网注册好应用,直接使用就可以了。
常见问题
手动上传符号表的时候,本地没有java环境,或者java环境不匹配终端报错内容:错误:尝试打开文件buglyqq-upload-symbol.jar时出现意外错误
终端查看了java的版本是18的,版本太高了,需要java 1.8的,所以换了自己的电脑用1.8的版本就可以成功上传符号表了。