SDK 功能介绍

1. 配置功能开关

配置类默认都开启,如果用户需要关闭部分功能,请在初始化appkey之前配置好。

请注意:此处的配置开关优先级低于产品后台「开关与采样配置」中设置的开关,如果您在产品后台中进行开关/采样率更改,将在下次启动时下发并覆盖此处配置的开关情况。

调整开关分为两个配置类:

  • UMAPMConfig包含崩溃和卡顿的配置;

  • UMEFSConfig包含启动分析、网络分析、内存分析、应用内H5页面分析、OOM异常、原生页面分析、日志回捞。

1.1 UMAPMConfig类开关

UMAPMConfig类为UMAPM中各个模块提供配置打开或关闭功能。

@interface UMAPMConfig : NSObject<NSCopying>

+(UMAPMConfig*)defaultConfig;

/**
 * crash&卡顿监控开关,默认开启
 */
@property (nonatomic,assign) BOOL crashAndBlockMonitorEnable;

/*
 * 卡顿监控参数
 * 发送检测心跳的时间间隔。单位:秒。
 * 区间范围[1,4],超过就用默认值2
 */
@property (nonatomic, assign) float sendBeatInterval;

/*
 * 卡顿监控参数
 * 检测卡顿的时间间隔 单位是秒。 (发送心跳后checkBeatInterval秒进行检测)
 * 区间范围[1,4],超过就用默认值2
 */
@property (nonatomic, assign) float checkBeatInterval;
 
/*
 * 卡顿监控参数
 * 连续多少次没心跳 认为触发卡顿
 * 区间范围[1,4],超过就用默认值3,注意此参数必须为整数
 */
@property (nonatomic, assign) NSInteger toleranceBeatMissingCount;

@end

配置模块

配置变量名

默认值

crash&卡顿模块

crashAndBlockMonitorEnable

YES

示例

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
     UMAPMConfig* config = [UMAPMConfig defaultConfig];
     config.crashAndBlockMonitorEnable = YES;
     [UMCrashConfigure setAPMConfig:config];
  
     [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
     [QTConfigure initWithAppkey:@"您的appkey" channel:@"App Store"];
}

1.2 UMEFSConfig

UMEFSConfig类为UMEFS中各个模块的提供配置打开或关闭功能。

@interface UMEFSConfig : NSObject

+(UMEFSConfig*)defaultConfig;

/**
 * 启动模块监控开关,默认开启
 */
@property (nonatomic,assign) BOOL launchMonitorEnable;

/**
 * 内存模块监控开关,默认开启
 */
@property (nonatomic,assign) BOOL memMonitorEnable;

/**
 * 网络模块监控开关,默认开启
 */
@property (nonatomic,assign) BOOL networkEnable;

/**
 * H5打通模块开关,默认开启
 */
@property (nonatomic,assign) BOOL javaScriptBridgeEnable;

/**
 * OOM模块监控开关,默认开启
 */
@property (nonatomic,assign) BOOL oomMonitorEnable;

/**
 * 原生页面模块监控开关,默认开启
 */
@property (nonatomic,assign) BOOL pageMonitorEnable;

/**
 * 日志回捞模块开关,默认开启
 */
@property (nonatomic,assign) BOOL logCollectEnable;

/**
 * 日志回捞模块userId
 */
@property (nonatomic,copy) NSString *logCollectUserId;


/**
 * 初始化主动发送PV
 */
@property (nonatomic, assign) BOOL initSendPVEnable;

@end

配置模块

配置变量名

默认值

启动模块开关

launchMonitorEnable

YES

网络模块开关

networkEnable

YES

内存模块开关

memMonitorEnable

YES

H5模块开关

javaScriptBridgeEnable

YES

OOM模块开关

oomMonitorEnable

YES

原生页面模块开关

pageMonitorEnable

YES

日志回捞模块开关

logCollectEnable

YES

日志回捞模块userId

logCollectUserId

初始化主动发送PV

initSendPVEnable

NO

示例:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     
    UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
    configForEFS.networkEnable = YES;
    configForEFS.launchMonitorEnable = YES;
    configForEFS.memMonitorEnable = YES;
    configForEFS.javaScriptBridgeEnable = YES;
    configForEFS.oomMonitorEnable = YES;
    configForEFS.pageMonitorEnable = YES;
    configForEFS.logCollectEnable = YES;
    configForEFS.logCollectUserId = @"日志回捞模块userId";
    configForEFS.initSendPVEnable = YES;
    [UMEFSConfigure setAPMConfig:configForEFS];

    [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
    [QTConfigure initWithAppkey:@"您的appkey" channel:@"App Store"];
  
    return YES;
}

2. 功能模块配置

2.1 崩溃分析

如您完成commonapm插件集成,完成初始化即可使用崩溃分析功能。

可选补充功能:崩溃回调(产品中可在错误详情-自定义字段tab中查看)

崩溃回调说明:当崩溃发生时,您可以通过此回调到您的业务逻辑,该接口返回string类型数据,该返回的数据会写入到崩溃文件中并上传到服务器展示。崩溃回调的限制为256个字符

回调接口:

//return字符串不能大于256字节,大于部分将被截取
+(void)setCrashCBBlock:(CallbackBlock_Nullable)cbBlock;

接口示例:

[UMCrashConfigure setCrashCBBlock:^NSString*_Nullable{

    return@“崩溃时自定义字符串”;
}];

上传后即可在错误详情-自定义字段中查看到回调信息:

下图做功能演示示例:

image

2.2 自定义异常

设置用户的自定义异常上传功能

接口函数:

/**
 * 上报自定义错误
 * @name 名称 长度限制256字节以内,超过截断。
 * @reason 错误原因 长度限制256字节以内,超过截断。
 * @stackTrace 堆栈 长度限制100*1024字节以内,超过截断。
 *
 * @example:
 * // 日志类型唯一标识
 NSString* name = @"myUnity";
 NSString* reason = @"csharp exception";

 NSArray* stackTrace = [NSArray arrayWithObjects:
 @"msg: Exception: Exception, Attempted to divide by zero.",
 @"UnityDemo+ExceptionProbe.NormalException () (at <unknown>:0)",
 @"UnityDemo.TrigException (System.Int32 selGridInt) (at <unknown>:0)",
 @"UnityDemo.OnGUI () (at <unknown>:0)",
 nil];
 *
 *[UMCrashConfigure reportExceptionWithName:name reason:reason stackTrace:stackTrace];
 *
 *
 */
+(void)reportExceptionWithName:(NSString* _Nonnull)name reason:(NSString* _Nonnull)reason stackTrace:(NSArray* _Nonnull)stackTrace;

示例:

NSString* name = @"myUnity";
NSString* reason = @"csharp exception";

NSArray* stackTrace = [NSArray arrayWithObjects:
 		       @"msg: Exception: Exception, Attempted to divide by zero.",
 		       @"UnityDemo+ExceptionProbe.NormalException () (at <unknown>:0)",
                       @"UnityDemo.TrigException (System.Int32 selGridInt) (at <unknown>:0)",
 		       @"UnityDemo.OnGUI () (at <unknown>:0)",
                       nil];
 
[UMCrashConfigure reportExceptionWithName:name reason:reason stackTrace:stackTrace];

功能演示示例:image

2.3 卡顿分析

卡顿分析需要集成基础组件库UMAPM.frameworkUMEFS.framework方能开启

通过配置项crashAndBlockMonitorEnable选项设置为YES即可开启卡顿模块

示例:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UMAPMConfig* config = [UMAPMConfig defaultConfig];
    config.crashAndBlockMonitorEnable = YES;
    [UMCrashConfigure setAPMConfig:config];

    [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
    [QTConfigure initWithAppkey:@"您的appkey" channel:@"App Store"];
}

2.4 启动分析

2.4.1启动阶段定义说明

启动分为冷启动和热启动:

冷启动

默认监控四个预定义启动阶段:

  • Pre-初始化耗时:从进程开始函数exec开始到指定+load执行的阶段。

  • 初始化耗时:从指定的+load执行到finishLaunching的阶段。

  • 应用构建耗时:从finishLaunchingFirstVC.viewDidLoad()的阶段。(viewDidLoad里面还需要构建childview)

  • 首页面加载耗时:从FirstVC.viewDidLoad()到FirstVC.viewDidAppear()结束,首次渲染完成。

热启动

  • applicationWillEnterForeground()开始到applicationDidBecomeActive()结束。

2.4.2 启动监控的方式

启动监控分自动监控和手动监控两种模式。

两种模式可以交叉使用,以用户手动埋点方式为准。

2.4.2.1 自动模式

用户只需要初始化appkey即可。

用户也可以设置可选的操作来设置首ViewController来明确首页面,保证正确的监控冷启动首页面的加载耗时。

相关的API如下:

+(void)setRootVCCls:(Class)cls;//在DidFinishLaunching第一句代码提前设置RootViewController

注意

如果没有设置,我们会寻找[UIApplication sharedApplication]的delegatewindowrootViewController为监控生命周期。

2.4.2.2 手动模式

目前手动模式只支持冷启动/首次启动阶段的埋点

相关的API如下:

/*
 * 手动设置三个预定义时间结束时间(初始化耗时结束,应用构建耗时结束,页面加载耗时结束)*/
+(void)setPredefineLaunchType:(UMPredefineLaunchType)predefineLaunchType;

目前给出的冷启动的三个预定义阶段的埋点分别为:

1、初始化耗时结束时间点(UMPredefineLaunchType_DidFinishLaunchingEnd)。

2、应用构建耗时结束时间点(UMPredefineLaunchType_ViewDidLoadEnd)。

3、首页面加载完成的结束时间点(UMPredefineLaunchType_ViewDidAppearEnd)。

分别对应的枚举变量为:

//冷启动的预定义类型
typedef NS_ENUM(NSInteger,UMPredefineLaunchType){
 UMPredefineLaunchType_DidFinishLaunchingEnd,//在didFinishLaunchingWithOptions的最后一句设置
 UMPredefineLaunchType_ViewDidLoadEnd,//在第一个ViewController的viewDidLoad函数的最后调用
 UMPredefineLaunchType_ViewDidAppearEnd//在第一个ViewController的viewDidAppear函数的最后调用
};

初始化耗时结束时间点示例

用户需要在系统回调函数的didFinishLaunchingWithOptions的函数最后埋点,以保证准确性

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

   [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];

   //在didFinishLaunchingWithOptions的最后埋点,以保证准确性
   [UMLaunch setPredefineLaunchType:UMPredefineLaunchType_DidFinishLaunchingEnd];
 
   return YES;
}

首页面加载耗时结束时间点示例

用户需要在第一个ViewControllerviewDidAppear的函数最后埋点,以保证准确性。

- (void)viewDidAppear {

  [super viewDidAppear];
 
  //在viewDidAppear的最后埋点
  [UMLaunch setPredefineLaunchType:UMPredefineLaunchType_ViewDidAppearEnd];
 }

用户自定义阶段埋点

用户自定义阶段埋点只能在冷启动阶段埋点,用户统计某个函数或者代码块的执行时间,方便客户细化启动阶段。

请注意:

1、beginLaunchendLaunch必须配对使用

2、beginLaunchendLaunch的调用时机必须在冷启动界面viewDidAppear之前调用,后续的调用无效

3、beginLaunchendLaunch的参数长度不能大于10个字符

4、beginLaunchendLaunch的数量不能超过10对,如果超过10对的话,后添加的会直接抛弃

相关的API如下:

/*
 * 用户在冷或者热启动阶段设置自己的自定义阶段
 * @note beginLaunch和endLaunch必须要配对调用
 * 如果调用时间段,不在页面加载耗时结束前调用,是不会上报的
 */
+ (void)beginLaunch:(NSString *)methodName;
+ (void)endLaunch:(NSString *)methodName;

示例:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [UMLaunch beginLaunch:@"initCommon"];
    [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];
    [UMLaunch endLaunch:@"initCommon"];
    [UMLaunch setPredefineLaunchType:UMPredefineLaunchType_DidFinishLaunchingEnd];
 
    return YES;
}

2.5 网络分析

2.5.1网络分析适用范围

  • 目前网络模块支持iOS系统的URL Loading System,支持iOS8及以上操作系统。

  • 目前支持NSURLSession大部分通用API网络捕获(httphttps)。

  • 目前并不支持iOS低版本的NSURLConnection相关API。目前不支持Socket捕获。

  • 目前支持AFNetworking的所有版本。

注意:集成NSURLProtocol的三方SDK的时候,会出现有系统版本不兼容引起的崩溃,解决方法可以参考2.5.3节。

2.5.2 网络分析捕获内容说明

网络模块目前捕获了网络各个阶段的开始结束时间,上行和下行流量及对应的URL

注意

如果要开启网络,需要app发起网络前开启网络配置项,方能捕获到全量数据,否则网络捕获功能可能会缺失数据或者失效

和其他三方网络库一起的时候,可能会产生冲突,导致网络模块失效。

1.请查看enableNetworkForProtocol函数的说明,根据需求调用。

示例:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSLog(@"UMEFS version:%@",[UMEFSConfigure getVersion]);
    UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
    configForEFS.networkEnable = YES;
    configForEFS.launchMonitorEnable = YES;
    configForEFS.memMonitorEnable = YES;
    configForEFS.javaScriptBridgeEnable = YES;
    configForEFS.oomMonitorEnable = YES;
    [UMEFSConfigure setAPMConfig:configForEFS];

    [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
    [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];

    return YES;
}

2.日志检查是否生效

一旦网络模块生效后,会在xcode中打印如下日志就代表成功:UMAPM_NetworkSampling打印出YES后,就表示网络模块开启并采样生效。

2021-09-13 14:24:24.962273+0800 QTAPMDemo[386:36277] UMAPM_NetworkEnable(1:1):1 2021-09-13 14:24:24.977290+0800 QTAPMDemo[386:36277] UMAPM_NetworkSampling(1,1):YES

一旦看到开启成功的日志,就可以发送一条网络请求来测试后端能否收到,网络示例代码如下: 发送成功后,即可在后端界面上看到对应的URL的网络请求:

//因Get请求有缓存,响应的内容会直接在本地获取直接返回
#define NetworkURL @"https://www.aliyun.com/"

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:NetworkURL]];
request.HTTPMethod = @"GET";
[request addValue:@"application/html" forHTTPHeaderField:@"Content-Type"];
    
NSURLSessionDataTask* dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
  if (data) {
      NSString* str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
      NSLog(@"str:%@",str);
  } else if (error) {
      NSLog(@"error:%@",error);
  }
}];
[dataTask resume];

2.5.3 集成NSURLProtocol和性能监控网络分析模块注意事项

增加网络分析模块在iOS13及以下系统的单独开关,以避免在同时集成NSURLProtocolAPM SDK的网络模块的本身冲突引起崩溃,特增加enableNetworkForProtocol函数。

发生问题的现象请见:https://developer.umeng.com/docs/193624/detail/352123

配置的函数说明如下:

/**
 * @brief 设置APM的网络模块针对iOS13及以下系统的单独开关,以避免在同时集成NSURLProtocol和APM SDK的网络模块的本身冲突引起崩溃。
 * 如果需要调用,在初始化APM SDK 的网络模块前调用。
 *
 * @param enable 指定开关。YES:捕获iOS13及以下特定网络请求,默认开启。NO:不捕获iOS13及以下特定网络请求。
 *
 * @note 问题原因:同时集成NSURLProtocol和APM SDK的网络模块的场景,先初始化APM SDK的网络模块,再初始化NSURLProtocol的registerClass,会导致崩溃在iOS13及以下版本会崩溃,目前可以确定为iOS系统API引起的问题,iOS14无此问题。(先初始化NSURLProtocol的registerClass,再初始化APM SDK的网络模块,是不会出现问题的)
 * 兼容iOS13及以下的初始化代码如下:
 * @example:
 * //确保NSURLProtocol的初始化在APM SDK的上面
 * [NSURLProtocol registerClass:[UMURLProtocol class]];
 * UMAPMConfig* config = [UMAPMConfig defaultConfig];
 * config.networkEnable = YES;
 * [UMCrashConfigure setAPMConfig:config];
 * [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];
 *
 * @note
 * 此开关默认打开,在同时集成NSURLProtocol和APM SDK的网络模块的场景时候,根据需要调用,如果按照上述初始化顺序,不需要调用。
 * 
 * @note 此函数关闭生效后,不会完全关闭网络模块,只是针对特定网络请求不再捕获,如果开发者能知道同时集成NSURLProtocol和APM的网络模块的场景的时候,建议通过调整初始化顺利来兼容所有场景,并在iOS13及以下版本测试兼容性。
 * @note:其他场景下,不需要调用此函数。
 */
+(void)enableNetworkForProtocol:(BOOL)enable;

2.6 内存分析

SDK 初始化前,将UMEFSConfig实例的memMonitorEnable属性设置为YES (注:默认开启)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
    configForEFS.networkEnable = YES;
    configForEFS.launchMonitorEnable = YES;
    configForEFS.memMonitorEnable = YES;
    configForEFS.javaScriptBridgeEnable = YES;
    configForEFS.oomMonitorEnable = YES;
    configForEFS.pageMonitorEnable = YES;
    [UMEFSConfigure setAPMConfig:configForEFS];

    [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
    [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];
  
    return YES;
}

2.7 OOM异常

通过配置项oomMonitorEnable选项设置为YES即可开启OOM模块。

测试时需要注意以下事项:

1、触发OOM时,app不能处于调试模式,与crash类似。

2、OOM是在下次启动时上传,且下次启动也不能处于调试模式。

以上两个操作步骤,都禁止debug模式。否则会影响到oom的监测和识别。

OOM模块需要集成基础组件库UMAPM.frameworkUMEFS.framework方能开启。

Release模式下如果测试设备用数据线连接Xcode也会影响数据上报。

示例如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
    configForEFS.networkEnable = YES;
    configForEFS.launchMonitorEnable = YES;
    configForEFS.memMonitorEnable = YES;
    configForEFS.javaScriptBridgeEnable = YES;
    configForEFS.oomMonitorEnable = YES;
    configForEFS.pageMonitorEnable = YES;
    [UMEFSConfigure setAPMConfig:configForEFS];

    [QTConfigure setCustomDomain:@"您的收数服务域名" standbyDomain:@""];
    [QTConfigure initWithAppkey:@"您的appkey" channel:@"App Store"];
    
    return YES;
}

2.8 H5 页面分析

SDK 初始化前,将UMEFSConfig实例的javaScriptBridgeEnable属性设置为YES (注:默认开启)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
    configForEFS.javaScriptBridgeEnable = YES;
    [UMEFSConfigure setAPMConfig:configForEFS];

    [QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];
  
    return YES;
}

嵌入到App中的H5页面集成APM SDK后需要设置App应用包名白名单,桥接场景下H5不需要设置收数域名。

示例:

import { init } from '@umengfe/apm';
init({
  pageFilter: {
    mode: 'ignore',
    rules: []
  },
  pid:'您的AppKey',
  pkgList:['您的App应用包名']
});

2.9 原生页面

模块开关

SDK 初始化前,将UMEFSConfig实例的pageMonitorEnable属性设置为YES (注:默认开启)

UMEFSConfig* configForEFS = [UMEFSConfig defaultConfig];
configForEFS.pageMonitorEnable = YES;
[UMEFSConfigure setAPMConfig:configForEFS];

//初始化 QTConfigure 
[QTConfigure initWithAppkey:@"您的AppKey" channel:@"App Store"];

用户自定义埋点

用于统计某个函数或者代码块的执行时间,方便客户细化启动阶段。

注意:

1、trackBegintrackEnd必须配对使用

2、trackBegintrackEnd的调用时机必须在界面viewDidAppear结束之前调用,后续的调用无效

3、trackBegintrackEnd的参数长度不能大于10个字符。

4、trackBegintrackEnd的个数不能大于6个(以methodName为依据)。

@interface UMPage : NSObject

+ (void)trackBegin:(NSString *)methodName viewController:(UIViewController *)vc;
+ (void)trackEnd:(NSString *)methodName viewController:(UIViewController *)vc;

@end

2.10 日志回捞

2.10.1 模块开关

SDK 初始化前,将UMEFSConfig实例的logCollectEnable属性设置为YES (注:默认开启)

若需要自定义用户ID(识别ID),可以设置logCollectUserId:

  • logCollectUserId单次冷启动生命周期内有效,不能变更

  • logCollectUserId长度不能超过128字节

2.10.2 日志打点接口

日志打点接口一共提供了5个不同类型的日志等级,代表日志严重程度的五个等级,可以在平台查看日志时进行筛选。

@interface UAPMLog : NSObject

+ (void)verbose:(NSString *)tag format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3);

+ (void)debug:(NSString *)tag format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3);

+ (void)info:(NSString *)tag format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3);

+ (void)warn:(NSString *)tag format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3);

+ (void)error:(NSString *)tag format:(NSString *)format, ... NS_FORMAT_FUNCTION(2,3);

@end

引入头文件:

#import <UMEFS/UAPMLog.h>

参数限制:

  • Tag限制:64字节

  • msg限制:1024 字节

示例:

[UAPMLog verbose:@"verbose_test" format:@"测试verbose类型日志"];
[UAPMLog debug:@"debug_test" format:@"测试debug类型日志"];
[UAPMLog info:@"info_test" format:@"测试info类型日志"];
[UAPMLog warn:@"warn_test" format:@"测试warn类型日志"];
[UAPMLog error:@"error_test" format:@"测试error类型日志"];

3. 符号表配置

3.1 什么是符号表

符号表是内存地址与函数名、文件名、行号的映射表。符号表元素如下所示:<起始地址> <结束地址> <函数> [<文件名:行号>]为了能快速并准确地定位用户APP发生Crash的代码位置,我们使用符号表APP发生Crash的程序堆栈进行解析还原

3.2 为什么要上传符号表?

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

举一个例子

image

性能监控提供了手动上传符号表

3.3 iOS符号表配置方式

什么是dsym文件?

iOS 平台中,dSYM 文件是指具有调试信息的目标文件存储着文件名、方法名、行号等信息,是和可执行文件的16进制函数地址一一对应的,通过分析崩溃的崩溃文件可以准确知道具体的崩溃信息。文件名通常为:xxx.app.dSYM,其中 xxx 通常表示应用程序的二进制包名,如下图所示:

通常我们可以在 Xcode 打包出来的文件xcarchive里面看到 dSYM 文件以及目录架构:

imageimage

如何定位dsym文件?

工程中获取

一般情况下,项目编译完dSYM文件跟app文件在同一个目录下,下面以XCode作为IDE详细说明定位dSYM文件。

-> 进入XCode;

-> 打开工程(已编译过);

-> 在左栏找到“Product”项;

-> 鼠标右键点击编译生成的“xxx.app”;

-> 点击“Show in Finder”;

如下图所示:

image

如果有多个dSYM文件,可以在使用工具时指定输入为dSYM文件所在的目录或者工程目录。

3.4 其他符号表相关问题

1.XCode编译后没有生成dSYM文件?

XCode Release编译默认会生成dSYM文件,而Debug编译默认不会生成,对应的Xcode配置如下:

XCode -> Build Settings -> Code Generation -> Generate Debug Symbols -> Yes

XCode -> Build Settings -> Build Option -> Debug Information Format -> DWARF with dSYM File

imageimage

2.开启Bitcode之后需要注意哪些问题?

  • 在点“Upload to App Store”上传到App Store服务器的时候需要声明符号文件(dSYM文件)的生成:

image

  • 在配置符号表文件之前,需要从App Store中把该版本对应的dSYM文件下载回本地,如下图。

注意:

不要使用本地生成的dSYM文件来生成符号表文件。由于本地编译生成的dSYM文件的符号表信息都被隐藏了,如果用本地编译生成的dSYM文件生成符号表文件并配置到U-APM平台之后,还原出来的结果将是类似于“__hiden#XXX”这样的符号。

image

3.如何判断dSYM文件是否与堆栈的UUID匹配?

还原Crash堆栈时,需要根据UUID来匹配符号表文件,因此只有上传的符号表文件的UUIDCrash对应APPUUID一致时,才能准确地对堆栈进行还原。

需要确定在 APM 符号表管理所选版本的uuidcrash崩溃堆栈中Binary Images的 uuid一致(符号表管理中uuid末尾的0 可忽略)

imageimage

4.如何查看dSYM文件的UUID?

通过命令查看UUID

xcrun dwarfdump --uuid <dSYM文件>

通过符号表文件查看UUID

符号表文件的UUIDdSYM文件的UUID是一致的,因此可以通过符号表工具生成的符号表文件来查看dSYM文件的UUID:

生成符号表文件(.zip) ---> 解压符号表文件(.symbol) ---> 使用文本编辑器打开符号表文件

image

其中符号表文件的“UUID”信息即Debug SO文件的UUID,亦是符号表文件的UUID,如果文件较大,建议使用“Sublime Text”等文本编辑器来打开符号表文件。

5.如何找回已发布到App StoreApp对应的dSYM文件?

通过Xcode找回

1、打开 Xcode 顶部菜单栏 -> Window -> Organizer 窗口:

image

2、找到发布的归档包,右键点击对应归档包,选择Show in Finder操作:

image

3、右键选择定位到的归档文件,选择显示包内容操作:

image

4、选择dSYMs目录,目录内即为下载到的 dSYM 文件:

image

通过iTunes Connect找回

1、登录iTunes Connect

2、进入“TestFlight”的“构建版本”页面:

image

3、择对应版本,点“下载dSYM”下载dSYM文件:

image

通过mdfind工具找回

U-APM 错误详情页面查询到crash对应的UUID:

然后在MacShell中,用mdfind命令定位dSYM文件:

mdfind"com_apple_xcode_dsym_uuids == <UUID>"

注意:使用mdfind时,UUID需要格式转换(增加“-”): 12345678-1234-1234-1234-xxxxxxxxxxxx

例如,要定位的dSYMUUID为:E30FC309DF7B3C9F8AC57F0F6047D65F 则定位dSYM文件的命令如下:

mdfind"com_apple_xcode_dsym_uuids == E30FC309-DF7B-3C9F-8AC5-7F0F6047D65F"|12345678-1234-1234-1234-xxxxxxxxxxxx|

建议每次构建或者发布APP版本的时候,备份App对应的dSYM文件!

image

当前支持上传方式:后台手动上传(最大支持400M)

3.5 符号表在产品中的使用

版本选择

当前支持现有版本列表和手动输入两种方式:

  1. 如果是已经有错误上报到U-APM后台的版本,可以直接在上传符号表时的版本下拉框中选择

  2. 如果是即将发布的新版本,支持手动输入版本号,请输入与新版本完全一致的内容,并点击‘添加版本号‘即可手动添加

image

  1. 按照文档说明将符号表文件压缩到一起

  2. 登录平台,找到需要上传的符号表应用,点击顶部的 设置 进入应用设置界面

  3. 点击符号表管理 ,点击 上传 ,将第一步压缩好的符号表文件上传即可