# 自动采集

> 来源：https://help.gravity-engine.com/docs/client-sdk/ios/advanced/automatic-tracking
> 介绍 Gravity Engine iOS SDK 支持自动采集的基础事件、开启方式及相关配置。



iOS SDK 支持包括安装、启动、关闭、页面浏览、元素点击等在内事件的自动采集。

## 1. 介绍 [#1-介绍]

`GravityEngineSDK` 提供自动化收集数据的接口，您可根据业务需求自行选择需要自动收集的数据。

目前支持的自动采集事件类型有：

* 安装事件：记录 APP 被安装的行为
* 启动事件：包括打开 APP 和从后台打开 APP
* 关闭事件：包括关闭 APP 和 App 进入后台，同时收集启动的时长
* 浏览事件：用户在 APP 中浏览页面（原生页面）
* 点击事件：用户在 APP 中点击控件
* 崩溃事件：APP 发生崩溃时记录崩溃信息

接下来将会对每种类型的自采集事件做详细介绍。

## 2. 开启自动采集 [#2-开启自动采集]

您需要手动调用`enableAutoTrack`，来打开自动采集功能：

```objective-c
[[GravityEngineSDK startWithConfig:config]enableAutoTrack:
GravityEngineEventTypeAppStart |//APP 启动事件，记录 APP 启动或从后台恢复
GravityEngineEventTypeAppInstall |//APP 安装，记录 APP 被安装的日志
GravityEngineEventTypeAppEnd |//APP 关闭事件，记录 APP 调入后台
GravityEngineEventTypeAppViewScreen |//APP 浏览页面事件
GravityEngineEventTypeAppClick |//APP 点击控件事件
GravityEngineEventTypeAppViewCrash];//APP 崩溃事件
```

## 3. 详细介绍 [#3-详细介绍]

### 3.1 安装事件 [#31-安装事件]

APP 安装事件将会记录 APP 的实际安装，在 APP 启动时上报，事件触发时间是 APP 安装后首次启动的时间，APP 升级并不会触发安装事件，而删除重装后会上报安装事件。

* 事件英文名：`$AppInstall`

### 3.2 启动事件 [#32-启动事件]

APP 启动事件将会在用户开启 APP，或从后台唤醒 APP 时触发。

* 事件英文名：`$AppStart`
* 预置属性：`$resume_from_background`，布尔型，表示 APP 是用户开启还是从后台唤醒，取值为 true 表示从后台唤醒，false 为直接开启。

### 3.3 关闭事件 [#33-关闭事件]

APP关闭事件会在用户退出或切换至后台时触发。如果此时网络正常，事件会立即上报；&#x2A;*但如果应用进程被系统强制结束或用户主动杀死，导致上报失败，该事件便会保存在本地。** 用户下次启动应用时，SDK会重新尝试上报这些暂存的事件。需要注意的是，如果用户在事件成功上报前卸载了应用，本地保存的所有数据将会被清除，相关事件会永久丢失。

* 事件英文名：`$AppEnd`
* 预置属性：`$event_duration`，数值型，表示该次 APP 访问（自启动至结束）的时长，单位是秒。

设置前台会话阈值（频繁切换前后台时，AppEnd 时间会很小，可通过此配置忽略这类操作）。当 AppEnd 发生时，如果事件时长小于设定的阈值，则忽略计时。

```objective-c
config.foregroundSessionThreshold = 10;
```

### 3.4 浏览页面事件 [#34-浏览页面事件]

APP 浏览页面事件将在用户切换页面（View Controller）时触发。

* 事件英文名：`$AppView`
* 预置属性：
  * `$screen_name`，字符串型，为 View Controller 的类名
  * `$title`，字符串型，为 View Controller 的标题，取值为 controller.navigationItem.title 属性的值

页面浏览事件中可以加入其它属性以扩展其分析价值，以下是自定义浏览页面事件属性的方法：

#### 3.4.1 自定义页面浏览事件的属性 [#341-自定义页面浏览事件的属性]

对于继承自 `UIViewController` 的 View Controller，您可以通过实现 `Protocol` 来设置属性以及页面的 URL 信息，SDK 将会自动将 `getTrackProperties` 的返回值加入到该 View Controller 的 APP 浏览页面事件中；另外 `getScreenUrl` 的返回值将会作为该页面的 URL Schema，当触发该页面的浏览事件时，将会加入预置属性 `$url`，取值即为当前页面的 URL Schema，同时 SDK 会取跳转前页面的 URL Schema，如果能取到则会加入到预置属性 `$referrer` 中，即前向地址。

```objective-c
@interface MYController : UITableViewController<GEScreenAutoTracker>
@end

@implementation MYController

- (NSDictionary *)getTrackProperties {
    return @{@"PageName" : @"商品详情页", @"ProductId" : @12345};
}

- (NSString *)getScreenUrl {
    return @"APP://test";
}
@end
```

相关预置属性：

* `$url`，字符串型，表示浏览页面的 URL
* `$referrer`，字符串型，表示页面跳转前页面的 URL

### 3.5 APP 控件点击事件 [#35-app-控件点击事件]

APP 控件点击事件将会在用户点击控件时触发

* 事件英文名：`$AppClick`
* 预置属性：
  * `$screen_name`，字符串型，为控件所在 `View Controller` 的类名
  * `$element_content`，字符串型，为控件的内容
  * `$element_type`，字符串型，为控件的类型
  * `$element_position`，字符串型，当控件存在 position 时才会上传

对于页面上控件的点击事件，有以下多种方式来设置更多属性，以扩展其分析价值：

#### 3.5.1 设置控件元素 ID [#351-设置控件元素-id]

您可以为页面上的元素（View）设置元素 ID 以区分不同意义的元素，可以使用如下方法设置元素 ID：

```objective-c
self.table1.gravityEngineViewID = @"testtable1";
```

此时 `table1` 的点击事件中会加入预置属性 `$element_id`，取值即为此处的传入值

* 相关预置属性：`$element_id`，字符串型，表示该元素的自定义 ID

#### 3.5.2 自定义控件点击事件的属性 [#352-自定义控件点击事件的属性]

对于大多数控件，可以直接使用 `gravityEngineViewProperties` 设置自定义属性：

```objective-c
self.table1.gravityEngineViewProperties = @{@"key1":@"value1"};
```

#### 3.5.3 UITableView 与 UICollectionView 控件点击事件的属性 [#353-uitableview-与-uicollectionview-控件点击事件的属性]

对于 `UITableView` 与 `UICollectionView`，则需要通过实现 `Protocol` 来设置自定义属性：

1. 首先在 View Controller 类中实现 `Protocol`
2. 其次在类中设置代理（建议在 `viewDidLoad` 方法中进行设置），`table1` 可替换为需要设置自定义属性的 View

```objective-c
self.table1.gravityEngineDelegate = self;
```

3. 之后根据 View Controller 的类型实现方法

* 此为 UITableView 需要实现的方法

```objective-c
//设置UITableView的自定义属性
-(NSDictionary *) gravityEngine_tableView:(UITableView *)tableView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath
{
    return @{@"testProperty":@"test"};
}
```

* 此为 UICollectionView 需要实现的方法

```objective-c
//设置UICollectionView的自定义属性
-(NSDictionary *) gravityEngine_collectionView:(UICollectionView *)collectionView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath
{
    return @{@"testProperty":@"test"};
}
```

4. 最后，在类中 `viewWillDisappear` 方法中将 `gravityEngineDelegate` 设置为 `nil`

```objective-c
-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    self.table1.gravityEngineDelegate = nil;
}
```

* `table1` 可替换为需要设置自定义属性的 View，与设置代理时对应

### 3.6 崩溃事件 [#36-崩溃事件]

当 APP 出现未捕获异常时，会上报 APP 崩溃事件

* 事件英文名：`$AppCrash`
* 预置属性：`$app_crashed_reason`，字符型，记录崩溃时的堆栈轨迹

## 4. 忽略自动采集事件 [#4-忽略自动采集事件]

您可以通过以下方式，忽略某页面或控件的自动采集事件

### 4.1 忽略某个页面的自动采集事件 [#41-忽略某个页面的自动采集事件]

对于某些页面（View Controller），如果不想传输自动采集事件（包括页面浏览与控件点击事件），可以通过以下方法进行忽略：

```objective-c
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:@"IgnoredViewController"];

[[GravityEngineSDK sharedInstance] ignoreAutoTrackViewControllers:array];
```

### 4.2 忽略某个类型控件的点击事件 [#42-忽略某个类型控件的点击事件]

如果需要忽略某个类型控件的点击事件，可以使用以下方法进行忽略

```objective-c
[[GravityEngineSDK sharedInstance] ignoreViewType:[IgnoredClass class]];
```

* `ignoredClass` 即为需要忽略的控件类型

### 4.3 忽略某个元素（View）的点击事件 [#43-忽略某个元素view的点击事件]

如果希望忽略某个元素（View）的点击事件，可以使用以下方法进行忽略

```objective-c
self.table1.gravityEngineIgnoreView = YES;
```

* `table1` 可替换为需要忽略的 View

## 5. 设置自定义属性 [#5-设置自定义属性]

您可以调用 `enableAutoTrack:properties` 打开自动采集功能，同时设置自定义属性

```objective-c
// 自动化采集自定义属性
[[GravityEngineSDK sharedInstance] enableAutoTrack:GravityEngineEventTypeAll properties:@{@"auto_key1": @"auto_value1"}];
```

您也可以调用 `setAutoTrackProperties:properties` 设置或者更新自定义属性

```objective-c
[[GravityEngineSDK sharedInstance] setAutoTrackProperties:GravityEngineEventTypeAppEnd properties: @{@"auto_key2": @"auto_value2"};
```

## 6. 自动采集事件回调 [#6-自动采集事件回调]

您可以调用 `enableAutoTrack:callback:` 打开自动采集功能，在 callback 中对属性进行添加和更新。

```objective-c
[[GravityEngineSDK sharedInstance] enableAutoTrack:GravityEngineEventTypeAll callback:^NSDictionary * _Nonnull(GravityEngineAutoTrackEventType eventType, NSDictionary * _Nonnull properties) {
    if (eventType == GravityEngineEventTypeAppStart) {
      return @{@"addkey":@"addvalue"};
    }
    if (eventType == GravityEngineEventTypeAppEnd) {
      return @{@"updatekey":@"updatevalue"};
    }
    return @{};
}];
```

> **请不要在此回调中做耗时操作，否则会影响数据正常入库**
