# 秒针分析SDK部署指南(Flutter版本）

A mzanalytics flutter plugin project.


# 一、准备工作 🍭

##1. 版本限制

* Flutter SDK：`>=1.17.0` 。
* Xcode 版本:  `>=12.0`。

* **MZAnalytics*_*IOS*_*SDK**适用于 **iOS 9-iOS 14.0，请将iOS Deployment Target设置为iOS 9.0，**。【适配于iOS 14 beta 7】

* **MZAnalytics*_*Android*_*SDK**适用于**Android 2.3.3（API Level 10）**及以上的设备。


###建议：
建议将sdk初始化方法放在获取设备ID、存储等权限后执行，若将sdk 初始化方法放在授权之前，可能会影响激活归因等数据的准确性。
 

##2. Flutter项目添加依赖

将`mzanalytics `添加至`pubspec.yaml`引用。

```   
dependencies:  
mzanalytics: ^0.1.2
```   

在flutter项目中运行  `flutter pub get` 

##3. 集成准备
####3.1  为应用申请AppID
    在 http://tongji.cn.miaozhen.com 网站中创建一款应用，
    您将获得一串随机的“dc-”开头的数字ID，用于唯一标识您的一款应用。

####3.2  AppID说明

     appId为应用追踪的唯一标识，在站点信息内获取。
#### 3.3 iOS Xcode 环境配置方法

a. 添加编译参数，选择    TARGETS-->Build Settings-->Other Linker Flags，设置为**-ObjC**。必须添加该参数，否则会引起崩溃。   
b. 打开info.plist文件,点击加号添加一行 **App Transport Security Settings** ,再往该数组中添加一个   **Allow Arbitrary Loads**  元素，同时设为 YES。

#### 3.4 Android SDK 集成方法
导入SDK
请根据所用IDE选择导入方式：

Eclipse ADT
将 SDK 中的 **MZAnalytics*_*Android*_*SDK.jar** 文件拷贝到工程的 libs 文件夹中：右键选择**MZAnalytics*_*Android*_*SDK.jar** --> Build Path --> Add to Build Path。

Android Studio
在 Android Studio 项目的 app 文件夹中，新建 libs 文件夹。
将 SDK 中 **MZAnalytics SDK*_*Android*_*SDK.jar** 和aar文件文件拷贝到新建的 libs 文件夹中。
修改 app 文件夹中的 build.gradle 文件，添加 dependencies 依赖项：

```
dependencies {
      …
      implementation files('libs/MZAnalytics SDK_sdk_x.x.x.jar') 
      implementation files('libs/msa_mdid_x.x.x.aar')
      …
  }
```
在项目build.gradle的defaultConfig添加如下配置

```
ndk {
       abiFilters 'armeabi-v7a', 'x86', 'arm64-v8a', 'x86_64', 'armeabi'
    }
    packagingOptions {
        doNotStrip "*/armeabi-v7a/*.so"
        doNotStrip "*/x86/*.so"
        doNotStrip "*/arm64-v8a/*.so"
        doNotStrip "* /x86_64/*.so"
        doNotStrip "armeabi.so"
    }
```


将assets目录文件导入目标项目的assets。其中supplierconfig.json文件需修改里边对应内容，特别是需要设置 appid 的部分。需要设置 appid 的部分需要去对应厂商的应 用商店里注册自己的app。

### 3.5 Android SDK权限配置
常规权限
满足基本监测需要如下权限：

| 权限                   | 用途                                 |
| -------------------- | ---------------------------------- |
| INTERNET             | 允许程序联网和上报监测数据。                     |
| ACCESS_NETWORK_STATE | 允许检测网络连接状态，在网络异常状态下避免数据发送，节省流量和电量。 |
| READ_PHONE_STATE     | 允许访问手机设备的信息，通过获取的信息来唯一标识用户。        |
| ACCESS_WIFI_STATE    | 允许读取WiFi相关信息，在合适的网络环境下更新配置。        |
| READ_EXTERNAL_STORAGE    | 允许读取SD卡上存储的相关ID信息        。|
| WRITE_EXTERNAL_STORAGE    | 允许写入相关ID信息到SD卡上。        |

示例代码

```
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 网络状态相关权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 手机信息相关权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- SD卡读写权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
```
```
高版本手机不支持http协议，需要在<application>标签中添加以下配置：
    
android:usesCleartextTraffic="true" 
    
```


##4. 运行环境配置
### 4.1 iOS运行环境配置
a. cd到iOS项目目录。   
b. 终端执行  `pod install`。   
c. 打开`Runner.xcworkspace` ,在`Pods->Development->mzanalytics->..->Classes中找到sdkconfig.xml`, 拖到工程项目Runner中。

### 4.2 Android运行环境配置
 

a. 进入到android项目目录`app/src/main中`。       
b. 拷贝assets文件夹(包含sdkconfig.xml和supplierconfig.json)到`main`目录下。      
c. 在application标签中添加属性（appkey为纯数字）： 
   

        <meta-data
           android:name="com.miaozhen.mzsdk.appKey"
           android:value="xxxx" />
        <meta-data
           android:name="com.miaozhen.mzsdk.channelId"
           android:value="xxxxx" />
       


#二、秒针分析SDK使用

####flutter代码中引入头文件:
`
import 'package:mzanalytics/mzanalytics.dart';
`
##1. iOS调用示例

###1.1 初始化SDK 使用时将xxxx替换为实际的AppId
接口定义：

    Future<void>  ios_appid(String aid)

##### 参数说明

| 参数  | 类型     | 说明                                |
| ----- | -------- | ----------------------------------- |
| AppId | NSString | 网站创建站点时的站点id为您的AppId。 |



示例代码 ：   

    Mzanalytics.ios_appid("xxxx");
        
 
 
###1.2 页面监测 

接口定义：

     Future<void>  ios_trackPageView(var parameter) 

参数说明：

| 参数  | 类型     | 说明              |
| ----- | -------- | ----------------- |
| title | NSString | 页面名称 （必填） |

示例代码 ：

        Mzanalytics.ios_trackPageView({
          'pageTitle': "页面名称"
        });


###1.3  自定义事件
接口定义：

    Future<void>  ios_trackEvent(var parameter)

参数说明：

| 参数          | 类型      | 说明             |
| ------------- | --------- | ---------------- |
| eventClassify | NSString  | 事件分类(选填)   |
| eventAction   | NSString  | 事件动作(选填)   |
| eventTag      | NSString  | 事件标签(选填) |
| eventPrice    | NSInteger | 事件价值(选填) |

示例代码：

        Mzanalytics.ios_trackEvent({
          'eventClassify': '点击热门banner',
          'eventAction': 'Click',
          'eventTag': '点击',
          'eventPrice': 1
        });

###1.4 高级自定义事件  没有自定义维度时，customDimMetrics可不传
接口定义：

    Future<void>  ios_trackSiteCustomEvent(var parameter) 
    
参数说明：

| 参数             | 类型         | 说明                                                         |
| ---------------- | ------------ | ------------------------------------------------------------ |
| customEvent      | NSDictionary | 包含高级事件id、以及高级事件维度、指标数均以实际在                                                 系统中创建的⾼级事件为准。 |
| customDimMetrics | NSDictionary | 自定义维度和指标（可选）                                     |

 示例代码：
 
        Mzanalytics.ios_trackSiteCustomEvent({
          'CustomEvent': {
            "customActionId": "1",
            "customActionLabel1": "2020/01/10",
            "customActionLabel2": "15728749249",
            "customActionLabel3": "北京",
            "customActionValue1": "1"
          },
          'CustomDimMetrics': {
            "customDimension1": "点击信用卡",
            "customDimension2": "查看商品详情",
            "customMetrics1": "点击信用卡总用户数",
            "customMetrics2": "查看商品详情总用户数"
          }
        });
  备注：
事件ID必传，其他高级事件维度至少传一个。
customActionLabel最多20个，名称为customActionLabel1~20。
customActionValue最多20个，名称为customActionValue1~20。
customDimension最多25个，名称为customDimension1~25。
customMetrics最多25个，名称为customMetrics1~25。

实际使用时将高级事件维度、高级事件指标、自定义维度、自定义指标替换为实际回传值。


###1.5 页面隐藏或关闭（关闭页面或进入后台时调用）
接口定义：

         Future<void>  get ios_trackPulse
         
参数说明：  无          
 示例代码：
 
        Mzanalytics.ios_trackPulse;

###1.6 获取访客id（设备唯一ID）
接口定义：

           Future<String>  get ios_getCid 
    
参数说明：  无          

示例代码：

        Mzanalytics.ios_getCid;


###1.7 打印日志

接口定义：

       Future<void>  ios_setEnableLog(bool parameter) 


参数说明：

| 参数             | 类型         | 说明                                                         |
| ---------------- | ------------ | ------------------------------------------------------------ |
| isEnableLog      | BOOL | 是否打印日志,默认为NO       

示例代码：


        Mzanalytics.ios_setEnableLog(true);

###1.8 DeepLink和Universal Links
请在appDelegate.m页面中配置deeplink相关代码。
接口定义：

```
+(void)handleOpenURL:(NSURL *)url;
```

参数说明：

| 参数  | 类型     | 说明                   |
| ----- | --------  | --------------------  |
| url    | NSURL | 回调接收到的url   （必填） |

示例代码：

在AppDelegate.m的deeplink系统回调中现实本方法, 根据项目配置如下:

```
/**DeepLink */
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url 
    options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
     
     [MLTSiteManager  handleOpenURL:url];
      
    return YES;
    }
    
/**UniversalLinks */
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
      
    [MLTSiteManager handleOpenURL:userActivity.webpageURL];          
     
    return YES;
    }
    
```
##### 唤起链接说明

```
示例：
    mltsite://event/page/view/last?name=ceshi&age=30&mz_ca=2220134&mz_sp=35790
格式规范：
    scheme://host/path?key1=value1&key2=value2&mz_ca=2220134&mz_sp=35790
说明：
    1、问号?前面客户可以自己定义
    2、问号后面key和value连接必须用=，不同key-value拼接必须用&
    3、同时存在mz_ca和mz_sp归为deeplink流量，否则归为普通流量
    4、mz_ca合法是7位，mz_sp合法是5位 
```



###1.9 SDKConfig权限配置
项目中 ***sdkconfig.xml*** 为sdk idfa权限开关配置文件，可以通过设置isRequired字段的value，当字段取值为true时，开启idfa的获取，当字段取值为false时，不获取idfa。
 

##2. Android调用示例



###2.1 初始化事件
接口定义：
  
       Future<void> android_initEvent()

参数说明：

| 参数        | 类型      | 说明                  |
| --------- | ------- | ------------------- |
| context   | Context | APP or Activity 上下文 |
| config | MzConfig  | SDK配置相关的类  |
| intent | Intent  | deeplink唤起页面传入getIntent()，其他情况传null即可  |

示例代码：

    try {
      Mzanalytics.android_initEvent();
    } on PlatformException {}


###2.2 基础事件
接口定义：
  
         Future<void> android_sendBaseEvent(var parameter)
 
参数说明：


| 参数        | 类型      | 说明  | 是否必填 | 
| --------- | ------- | ---- | --------- |
| dt   | String | 页面名称  | 必填  |
| ec   | String | 事件分类  | 必填  |
| ea   | String | 事件动作  | 必填  |
| el   | String | 事件标签  | 非必填 |
| ev   | String | 事件价值  | 非必填  |

示例代码：

    try {
      Mzanalytics.android_sendBaseEvent({
        "dt": '首⻚⻚面',
        "ec": '点击热⻔banner',
        "ea": 'Click',
        "el": '点击',
        "ev": '10',
      });
    } on PlatformException {}


###2.3 页面事件事件
接口定义：

       Future<void> android_pageEvent(var parameter) 
        
参数说明：

| 参数        | 类型      | 说明  | 是否必填 | 
| --------- | ------- | ---- | ------- |
| dt   | String | 页面名称 | 必填 |

            
示例代码：

     try {
      Mzanalytics.android_pageEvent({
        "dt": '底部导航栏',
      });
    } on PlatformException {}

###2.4 高级事件
接口定义：
 
      Future<void> android_seniorEvent(var parameter)

参数说明：

| 参数        | 类型      | 说明  | 是否必填 | 
| --------- | ------- | ---- | --------- |
| caid   | int | 高级事件id  | 必填  |
| cal[1~20] | String | 高级事件维度  | 必填  |
| cav[1~20]   | int | 高级事件指标  | 必填  |


示例代码：

    try {
      Mzanalytics.android_seniorEvent({
        "cal1": '提交订单',
        "cal2": '支付订单',
        "cav1": '提交订单数',
        "cav2": '支付订单数',
        "caid": '1',
      });
    } on PlatformException {}
    
###2.5 心跳事件
接口定义：
 
        Future<void> android_heartEvent() 
 
参数说明：无

示例代码：

     try {
      Mzanalytics.android_heartEvent();
    } on PlatformException {}
    
    
    
###2.6 获取cid
接口定义：
 
       Future<String> android_getCid()

参数说明：无

示例代码：

    try {
      String cid = await Mzanalytics.android_getCid();
    } on PlatformException {
    }    
    
###2.7 获取oaid
接口定义：

      Future<String> android_getOaid() 

参数说明：无

示例代码：
    try {
      String oaid = await Mzanalytics.android_getOaid();
    } on PlatformException {
    }       
    
###2.8 Deeplink配置
请在原生页面配置完成。
修改AndroidManifest.xml文件。
在接受deeplink唤起的activity配置中添加如下代码：

```
<intent-filter >
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="bj"
          android:pathPrefix="/site"
          android:scheme="miaozhen" />
</intent-filter>
```
#####唤起链接相关说明：
```
示例：
    miaozhen://bj/site?mz_ca=2000001&mz_sp=10000
格式规范：
    scheme://host/path?key1=value1&key2=value2&mz_ca=2220134&mz_sp=35790
说明：
    1、问号?前面客户可以自己定义
    2、问号后面key和value连接必须用=，不同key-value拼接必须用&
    3、同时存在mz_ca和mz_sp归为deeplink流量，否则归为普通流量
    4、mz_ca合法是7位，mz_sp合法是5位

```


在接收唤起事件Activity的onCreate()方法中初始化如下方法：

```
//SDK 配置相关
MzConfig config = new MzConfig();
//调试时设置log开关
config.setDebugMode(true);
//SDK初始化
MzSiteSDK mzSiteSDK =     MzSiteSDK.getInstance(getApplicationContext(),config,getIntent());
```


备注：如果想完整启动app，建议添加到启动页面。

###2.9 SDKConfig权限配置

项目中 ***sdkconfig.xml*** 为sdk imei、oaid权限开关配置文件，可以通过设置isRequired字段的value，当字段取值为true时，开启imei、oaid的获取，当字段取值为false时，不获取imei、oaid。
