文档

SDK API

更新时间:

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;

@end

配置模块

配置变量名

默认值

启动模块开关

launchMonitorEnable

YES

网络模块开关

networkEnable

YES

内存模块开关

memMonitorEnable

YES

H5模块开关

javaScriptBridgeEnable

YES

OOM模块开关

oomMonitorEnable

YES

原生页面模块开关

pageMonitorEnable

YES

日志回捞模块开关

logCollectEnable

YES

日志回捞模块userId

logCollectUserId

示例:

- (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";
    [UMEFSConfigure setAPMConfig:configForEFS];

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

2. 功能模块配置

2.1 崩溃分析

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

可选补充功能:崩溃回调(产品中可在错误详情-自定义字段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.framework和UMEFS.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的阶段。

  • 应用构建耗时:从finishLaunching到FirstVC.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]的delegate的window的rootViewController为监控生命周期。

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

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

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

- (void)viewDidAppear {

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

用户自定义阶段埋点

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

请注意:

1、beginLaunch和endLaunch必须配对使用

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

3、beginLaunch和endLaunch的参数长度不能大于10个字符

4、beginLaunch和endLaunch的数量不能超过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网络捕获(http或https)。

  • 目前并不支持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及以下系统的单独开关,以避免在同时集成NSURLProtocol和APM 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.framework和UMEFS.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、trackBegin和trackEnd必须配对使用

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

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

4、trackBegin和trackEnd的个数不能大于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来匹配符号表文件,因此只有上传的符号表文件的UUID与Crash对应APP的UUID一致时,才能准确地对堆栈进行还原。

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

imageimage

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

通过命令查看UUID

xcrun dwarfdump --uuid <dSYM文件>

通过符号表文件查看UUID

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

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

image

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

5.如何找回已发布到App Store的App对应的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:

然后在Mac的Shell中,用mdfind命令定位dSYM文件:

mdfind"com_apple_xcode_dsym_uuids == <UUID>"

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

例如,要定位的dSYM的UUID为: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. 点击符号表管理 ,点击 上传 ,将第一步压缩好的符号表文件上传即可

  • 本页导读