开始集成

集成前的准备工作

注册后台账号

后台地址为:https://dashboard.deepshare.io

提交注册申请后,请前往注册邮箱,在邮件中点击激活链接,即可进入管理后台,请按照 集成引导添加、集成APP。

关于AppID

首次登入开发者后台后,可以添加新App, 并获取AppID。AppID作为您的应用在DeepShare的唯一标识,在后继SDK集成环节需要被使用到。

接入DeepShare的同一个应用的iOS版本和Android版本可以使用同一个AppID,无需重新申请。使用同一个AppID可以支持iOS版本和Android版本等多平台版本的数据整合和对比统计。

DeepShare参数

DeepShare参数是DeepShare服务的核心元素,DeepShare参数通过DeepShare服务可以从Web端传递到App内部。

DeepShare的所有功能都是基于DeepShare参数实现的,例如场景还原,渠道检测,归因分析等。

以下分别介绍DeepShare参数的每一个域及其对应的功能,其中每一个域都是可选的。

场景还原

inapp_data:通过将应用内的场景还原参数(例如文章地址、商品ID等)设置到inapp_data域,当App启动时通过调用DeepShare的init方法,就可以得到此场景还原参数。
开发者可以选择通过集成Native SDK或者调用Web API(App端)来获取场景还原参数。当场景还原参数返回后,开发者可以根据参数信息进行场景的还原。
实例如下:

var data = {
    name : "mkdir",
}
var params = {
    inapp_data : data,
}

其中data中参数格式可以为任意Json数据格式,例如:

  • 字符串:name : “mkdir”,
  • 整 数:value : 1,
  • 布尔值:is_ok : true,

打开App时即可收到DeepShare启动参数。

如果inapp_data域为空,App被调起时就不会接收到场景还原参数。

渠道监测

channels:通过设置channels域,自动将安装前后的渠道绑定起来,之后可以通过Dashboard查看渠道的表现。
实例如下:

var params = {
    channels : ["chanName_chanType_chanNumber"],
}

归因分析

sender_id:通过native SDK获取,用于标识此分享的发起者。 此参数用于统计以及归因分析。

  • iOS: + (NSString *)getSenderID;
  • Android: public static String getSenderId();

自定义下载过程

download_title:可以附加显示在跳转商店页面的信息,可以给用户更好的引导。

download_msg:可以附加显示在跳转商店页面的信息,可以给用户更好的引导。

(此页面只会在iOS9 Universal Link的Web中转页面和Android直接下载APK的中转页面出现)

DeepShare参数实例

一个完整的DeepShare参数:

var data = {
    name : "mkdir",
}
var params = {
    inapp_data : data,
    channels:["chanName1_chanType1_chanNumber1"],
    sender_id : "senderID",
    download_title : "我是download_title",
    download_msg : "我是download_msg",
}

请参考以下两节内容以进行下一步集成。

  • Web API(网页端):(推荐方式)通过调用Web接口获取DeepShare Link, 通过DeepShare Link进行跳转。
  • JS API(网页端):通过调用DeepShare的JS接口,来实现DeepShare相关功能的方式。(Beta)

Web API(网页端)

Web API是网页端通过调用DeepShare的Web接口,返回一个绑定DeepShare参数的DeepShare链接。

当DeepShare链接被用户点击后,如果App已经被安装在手机上,App会被自动唤起;如果App未安装,DeepShare会引导用户进入商店或者直接下载安装。

无论哪种场景,当App启动时,调用DeepShare的SDK相应接口即可获取启动参数等相关信息。

DeepShare链接可以看成一个绑定APP初始化参数、渠道信息、发送方ID信息等Web信息的Deferred Deeplink链接。

其结构为:https://fds.so/d/#APP_ID/#Hash
例如:https://fds.so/d/38CCA4C77072DDC9/2LwCsozd9S

DeepShare链接具有如下特点:

  • 短连接,易于分享
  • 自适应浏览器(微信,微博,各种第三方安卓浏览器均已适配)
  • 支持iOS Universal Link
  • 转化率自动跟踪

通过DeepShare链接实现场景还原的典型流程如下图所示,其中黄色部分的流程需要调用DeepShare的接口来完成。

API接口说明

  • URL:https://fds.so/v2/url/用户申请的AppID
  • 请求方式:POST
  • 支持格式:JSON
  • 请求参数:DeepShare参数
var paramsJson = JSON.stringify(params)
$.post('https://fds.so/v2/url/#appID', paramsJson, function(result) {
      //deepshareUrl为所生成的DeepShare Link
      deepshareUrl = result.url;
 }).error(function() {
      //出错情况下可以继续用户正常逻辑,可设置一个默认url.
});

为了使跳转时有更好的体验,强烈建议采用以下调用方式:

var paramsJson = JSON.stringify(params)
$.ajax({
    url: 'https://fds.so/v2/url/#appID',
    type: 'POST',
    data: paramsJson,
    xhrFields: {withCredentials: true,},
    success: function(result) {
        //deepshareUrl为所生成的DeepShare Link
        deepshareUrl = result.url;
    },
    error: function() {
      //出错情况下可以继续用户正常逻辑,可设置一个默认url.
    },
});

EXAMPLE

以下通过一个真实的项目”Linux CMD”演示如何产生DeepShare Link:

URL

Perform a action!

Request

Perform a action!

Response

Perform a action!

Action

最佳实践

我们推荐的方法是在页面加载时调用接口生成本页面所需要的所有URL,用户点击时进行跳转: (使用此方式在iOS9并且开启Universal Link的情况下,从微信、QQ等打开DeepShare URL时可以进行直接跳转,不需要用户手动选择在Safari打开)

var deepshareUrl = null;
window.onload = function () {
    $.post('https://fds.so/v2/url/#appID', paramsJson, function(result) {
        deepshareUrl = result.url
    }).error(function() {
    });
};

跳转的时候直接将location.href设为DeepShare URL:

$('#openDeepShareUrl').click(function() {
    if(deepshareUrl != null){
        location.href = deepshareUrl;
    }else{
        //出错情况下可以继续用户正常逻辑.例如可以设置直接前往APP商店
    }
});


请参考以下三节内容以进行下一步集成。

  • Android SDK集成:(推荐)Android native SDK的集成方法
  • iOS SDK集成:(推荐)iOS native SDK的集成方法
  • Web SDK集成:App中直接调用Web接口的集成方法(不喜欢集成SDK的用户请走这里)

JS API(网页端)

JS API是网页端通过调用DeepShare的JS接口,来实现DeepShare相关功能的方式。
此功能目前处于Beta阶段。

使用JS API可以高度定制化DeepShare相关流程,例如定制化所有Landing Page等。

在需要调用的页面引入JS库文件 ,其文件地址为:

http://qn.fds.so/deepshare_v2.7.min.js

API接口说明

初始化

其中params为开发者自己组装的DeepShare参数

deepshare = new DeepShare(appid);
deepshare.BindParams(params);

基础接口

触发跳转

deepshare.Start();  // 开始跳转,调用后将立即跳转到目标(下载页面或APP内部)

回调接口

提示:DeepShare有成熟的默认处理方式,只有当需要高度定制跳转过程的时候才需要自己实现回调接口。

在某些少数情况下,不能跳转到目标地址,需要特殊处理。
这些情况包括:

  • 微信浏览中,没有应用宝地址且不支持universal link时
  • QQ浏览器中,没有应用宝地址且不支持univeral link时
  • weibo的内置浏览器中
  • 用户的设备没有对用的版本, 例如APP只开发了Android版本,但用户的设备是iOS
  • 一些特殊的浏览器的限制,不能进行跳转

在这些情况下,deepshare JS sdk 提供回调接口,方便开发者定制,为用户提供更好的体验。

deepshare.SetCallbackWeixinIOSTip(callback)        // 在iOS的微信浏览器时将调用此callback
deepshare.SetCallbackWeixinAndroidTip(callback)    // 在Android的微信浏览器时将调用此callback
deepshare.SetCallbackWeiboIOSTip(callback)         // 在iOS的微博浏览器时将调用此callback
deepshare.SetCallbackWeiboAndroidTip(callback)     // 在Android的微博浏览器时将调用此callback
deepshare.SetCallbackQQIOSTip(callback)            // 在iOS的QQ浏览器时将调用此callback
deepshare.SetCallbackQQAndroidTip(callback)        // 在Android的QQ浏览器时将调用此callback
deepshare.SetCallbackIOSNotAvailable(callback)     // iOS版本不存在时将调用此callback
deepshare.SetCallbackAndroidNotAvailable(callback) // Android版本不存在时将调用此callback
deepshare.SetCallbackCannotDeeplink(callback)      // 浏览器不能支持DeepLink跳转时将调用此callback
deepshare.SetCallbackAndroidDownloadLanding(callback) // 跳转下载地址时的LandingPage
deepshare.SetCallbackAndroidMarketLanding(callback) // 在Android跳转时的LandingPage
deepshare.SetCallbackAndroidCannotGoMarketLanding(callback) // 不能跳转Android市场的LandingPage

同时生成多个跳转

有时在一个web分享页面上需要有多个跳转App的入口,需要绑定不同的初始化参数,渠道参数等DeepShare参数
针对这种情况,JS API提供了方便的批量处理接口。通过数组的方式,传入多个跳转配置:

var params = new Array(
  {
    inapp_data: {
        name: 'mkdir',
    },
  },
  {
    inapp_data: {
        name: 'grep',
    },
  }
);

跳转时需要指定数组对应下标作为Start()方法的参数:

deepshare.Start(0);  // 0代表params array里第0个deepshare参数

EXAMPLE

以下通过一个真实的项目”Linux CMD”演示如何产生DeepShare Link:

单个跳转入口

<script type="text/javascript">
//组装参数
var params = {
    inapp_data: {
        name: 'mkdir',
    },
}

// 初始化DeepShare
var deepshare = new DeepShare('38CCA4C77072DDC9');
deepshare.BindParams(params);

document.getElementById('#GoToAppButton').addEventListener('click', function() {
    // 触发跳转
    deepshare.Start();
})
</script>

如果您正在使用手机浏览此页面,可以点击这个按钮体验。


多个跳转入口

<script type="text/javascript">
//组装参数
var params = new Array(
  {
    inapp_data: {
        name: 'mkdir',
    },
  },
  {
    inapp_data: {
        name: 'grep',
    },
  }
);

// 初始化DeepShare
var deepshare = new DeepShare('38CCA4C77072DDC9');
deepshare.BindParams(params);

document.getElementById('#GoToMkdir').addEventListener('click', function() {
    // 触发跳转
    deepshare.Start(0);
});
document.getElementById('#GoToGrep').addEventListener('click', function() {
    // 触发跳转
    deepshare.Start(1);
});
</script>

如果您正在使用手机浏览此页面,可以点击这个按钮体验。



请参考以下三节内容以进行下一步集成。

  • Android SDK集成:(推荐)Android native SDK的集成方法
  • iOS SDK集成:(推荐)iOS native SDK的集成方法
  • Web SDK集成:App中直接调用Web接口的集成方法(不喜欢集成SDK的用户请走这里)

Android SDK

相关系统代码

当Activity为singleTop或singleTask的启动模式时,需要在系统回调方法onNewIntent()中将intent设置为新收到的intent,DeepShare需要根据启动intent判断程序是否是通过DeepShare链接被激活的。
当Activity的启动模式不是singleTop或singleTask时,此方法也没有任何副作用,如果开发者不确定启动模式的话,建议添加。

示例代码如下:

@Override
public void onNewIntent(Intent intent) {
    this.setIntent(intent);
}

在Activity的onStop方法中,调用DeepShare.onStop()方法。

示例代码如下:

@Override
public void onStop() {
    super.onStop();
    DeepShare.onStop();//停止DeepShare
}

基本功能

获取场景还原参数API

DeepShare的核心功能是可以在应用启动时接收到分享者的预设参数,并根据这些参数进行场景的恢复。

/**
 * 初始化API,同时设置相应的监听器
 * @param activity 当前activity
 * @param appId APP注册时生成的APP ID.
 * @param inappDataListener 用来接收inappData回调的instance.
 */
public static void init(Activity activity, String appId, DSInappDataListener inappDataListener)

为实现场景还原功能,启动Activity需要实现DSInappDataListener接口。DSInappDataListener接口定义了场景调用成功时的回调函数onInappDataReturned。
在应用的启动Activity中,在onStart()方法里添加DeepShare.init方法,并通过重写异步回调方法onInappDataReturned()获取分享参数params

示例代码例如下:
(其中所返回参数”name”为DeepShare参数中所举实例中的参数)

public class MainActivity extends Activity implements DSInappDataListener {
    public void onStart() {
        super.onStart();
        DeepShare.init(this, "此处填写您申请的App ID", this);
    }
    
    @Override
    /** 代理方法onInappDataReturned处理获取的启动参数
    * @param params 所获取到的启动参数
    */
    public void onInappDataReturned(JSONObject params) {
        try {
                if (params == null) return;
                String cmdName = params.getString("name");
                goToLinuxCmd(cmdName); //调用应用自己的接口跳转到分享时页面
            } catch (JSONException e) {
                e.printStackTrace();
            }
    }

    @Override
    public void onFailed(String s) {

    }
}

用户归因API

返回分享者ID

通过此接口,可以获得唯一标识本用户在本App中的分享ID,可用于追踪用户分享源头。
通常用法是将此分享者ID传入网页端API组装DeepShare参数的JS代码中,作为sender_id的参数值生成DeepShare链接。

/**
 * 返回我的senderId
 */
public static String getSenderId()

获取分享带来的新使用

通过获取本用户分享带来的新用户的安装量及老用户的打开次数,开发者可以给此用户返利,以激励用户更多的分享,进而带来链式传播的效果

/**
 * 异步返回通过我的分享带来的此应用的新使用,新用户的安装量及老用户的打开次数
 *
 */
public static void getNewUsageFromMe(NewUsageFromMeListener callback){
}

此功能依赖于上一个接口getSenderId(),开发者需要将分享者ID传入网页端API组装DeepShare参数的JS代码中,否则此API的回调将会返回0值。
此方法调用将异步执行,异步执行结果通过回调接口onNewUsageFromMe()返回。
此接口定义为:

public interface NewUsageFromMeListener extends DSFailListener {
    /* 返回我的分享带来的新的使用
     * @param newInstall 新用户的下载安装量
     * @param newOpen 老用户的打开次数
     */
    public void onNewUsageFromMe(int newInstall, int newOpen);
}

清空分享带来的新使用

清空本用户分享带来的新用户的安装量及老用户的打开次数,一般在返利结束后调用此方法,用于清零。

/**
 * 清空通过我的分享带来的此应用的新使用,包括新安装的用户量和老用户的打开次数
 *
 */
public static void clearNewUsageFromMe(DSFailListener callback){
}

价值标签API

改变价值标签的值

/**
 * 改变指定价值标签的值,用户可以自定义事件的标签,如购买事件记录
 * @param tagToValue 所指定价值标签和其增加或减少的价值量所组成的HashMap.
 *
 */
public static void attribute(HashMap<String, Integer> tagToValue, DSFailListener callback)
  • 可以通过此接口,统计新用户及新使用带来的价值。一种场景是电商类应用可以通过此接口统计本用户分享所带来的价值,进而实现返利、赠送优惠券等营销活动
  • 此接口中tagToValue为标签和其对应的值,其中值是改变量
  • 此接口所改变的标签对应的值是属于深度链接分享者的,返利统计也会计算在分享者的名下

示例代码如下:

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("paidMoney", 888);
//在标签"paidMoney"下增加了888的值,如果paidMoney之前值为1000,调用接口后的值为1888
DeepShare.attribute(map, new DSFailListener(){
    @Override
    public void onFailed(String reason) {
    }
});

FAQ

当App在手机后台时,从微信中通过应用宝跳转至App后为何无法跳转至内容页面?

应用宝跳转时启动的不是App的LAUNCHER Activity, 而是App的当前Activity。所以如果DeepShare.init()方法在LAUNCHER Activity的onStart里调用而且当前Activity不是LAUNCHER Activity的话,App被调起时就无法跳转。
解决方法是使用Application的ActivityLifecycleCallbacks(需要翻墙)来监听整个Application的生命周期事件。

iOS SDK

Universal Link

Universal Link是Apple为iOS 9提供的一个新特性,通过Universal Link,App可以无需打开Safari,直接通过iOS系统启动。 在iOS9.2以后的版本中,如果继续通过Safari能否打开App Scheme来判断App是否安装,用户体验变得很差:

  • 如果App未安装,会出现错误对话框:
  • 如果App已安装,会出现一个确认打开的对话框。但是在iOS9.2以后,这个对话框由以前的模态对话框变成了非模态对话框,如果通过打开Scheme超时来判断是否安装,超时后会继续执行超时回调代码。 这样的话,即使在已经安装的情况下,还是会进入商店的下载页面。

因此,我们强烈推荐配置Universal Link,而通过DeepShare来配置Universal Link也变得非常简便。
去配置Universal Link

基本功能

获取场景还原参数

DeepShare的核心功能是可以在应用启动时接收到分享者的预设参数,并根据这些参数进行场景的恢复。

/** 初始化API,同时设置相应的委托对象
 * @param appId APP注册时生成的APP ID.
 * @param options launchOptions AppDelegate的didFinishLaunchingWithOptions方法所传回的参数
 * @param delegate 委托方法onInappDataReturned所在的类的对象
 * @return void
 */
+ (void)initWithAppID:(NSString *)appId withLaunchOptions:(NSDictionary *)options withDelegate:(id)delegate;

/** 委托方法onInappDataReturned
 * @param params 所获取到的启动参数
 * @param error 错误信息
 */
- (void)onInappDataReturned: (NSDictionary *) params withError: (NSError *) error {
}

在AppDelegate的didFinishLaunchingWithOptions方法中添加[DeepShare initWithAppID…]的调用,并通过Delegate接受返回的启动参数。 LaunchOptions是用来判断App是否是通过URL Scheme进行唤起的。 示例代码如下:
(其中所返回参数”name”为DeepShare参数中所举实例中的参数)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    [DeepShare initWithAppID:@"此处填写您申请的App ID" withLaunchOptions:launchOptions withDelegate:self];
    return YES;
}

- (void)onInappDataReturned: (NSDictionary *) params withError: (NSError *) error {
    if (!error) {
        NSLog(@"finished init with params = %@", [params description]);
        NSString *cmdName = [params objectForKey:@"name"];
        goToLinuxCmd(cmdName); //调用应用自己的接口跳转到分享时页面
    } else {
        NSLog(@"init error id: %ld %@",error.code, errorString);
    }
}

用户归因API

返回分享者的ID

通过此接口,可以获得唯一标识用户在本App中的分享ID,可用于追踪用户分享源头。
通常用法是将此分享者ID传入网页端API组装DeepShare参数的JS代码中,作为sender_id的参数值生成DeepShare链接。

/**
 * 获取分享者的ID
 */
+ (NSString *)getSenderID;

获取分享带来的新使用

通过获取本用户分享带来的新用户的安装量及老用户的打开次数,开发者可以给此用户返利,以激励用户更多的分享,进而带来链式传播的效果。

/**
 * 异步返回通过我的分享带来的此应用的新使用,新用户的安装量及老用户的打开次数
 *
 */
+ (void)getNewUsageFromMe:(callbackWithNewUsageFromMe)callback;

此功能依赖于上一个接口getSenderId,开发者需要将分享者ID传入网页端API组装DeepShare参数的JS代码中,否则此API的回调将会返回0值。
此方法调用将异步执行,异步执行结果通过block函数callbackWithNewUsageFromMe返回。
此接口定义为:

/* 返回我的分享带来的新的使用
 * @param newInstall 新用户的下载安装量
 * @param newOpen 老用户的打开次数
 * @param error 错误信息
 */
typedef void (^callbackWithNewUsageFromMe) (int newInstall, int newOpen, NSError *error);

清空分享带来的新使用

清空本用户分享带来的新用户的安装量及老用户的打开次数,一般在返利结束后调用此方法,用于清零。

/**
 * 清空通过我的分享带来的此应用的新使用,包括新安装的用户量和老用户的打开次数
 * @param callback 如果出错,错误信息会通过此block函数返回
 */
+ (void)clearNewUsageFromMe:(callbackWithError)callback;

价值标签API

改变价值标签的值

/**
 * 改变指定价值标签的值
 * @param tagToValue 所指定价值标签和其增加或减少的价值量所组成的NSDictionary.
 */
+ (void) attribute:(NSDictionary *)tagToValue completion:(callbackWithError)callback;
  • 可以通过此接口,统计新用户及新使用带来的价值。一种场景是电商类应用可以通过此接口统计本用户分享所带来的价值,进而实现返利、赠送优惠券等营销活动
  • 此接口中tagToValue为标签和其对应的值,其中值是改变量
  • 此接口所改变的标签对应的值是属于深度链接分享者的,返利统计也会计算在分享者的名下

示例代码:

NSString *tag = @"paidMoney";
NSNumber *value = @888;
NSDictionary *taggedvalue = [[NSDictionary alloc] initWithObjects:@[value] forKeys:@[tag]];
//在标签"paidMoney"下增加了888的值,如果paidMoney之前值为1000,调⽤用接⼝口后的值为1888
[DeepShare attribute:taggedvalue completion:^(NSError *error) { }];

FAQ

可能有多种原因,请依次排查。

  1. 请确认DashBoard中正确填写了Team Id。
  2. 因为Universal Link是App安装时激活的,如果是从XCode直接Debug版更新安装的,Universal Link可能不会被激活。请完全删除App后重新安装App。
  3. 请确保entitlements file关联了正确的target。因为一些原因,某些版本的Xcode 7并不会把entitlements file添加到build中,所以我们需要在project browser中手动将新生成的entitlements file添加到正确的target中,这样这个文件才会build。

导入lib后为何XCode显示很多warning?

这是XCode之前的一个bug,如果新工程是通过XCode7之前版本创建的,就会出现这个问题,如果新工程是通过XCode7之后版本创建的,就没有这个问题。
在Debug版本中其实并不需要dSYM文件,解决的方法就是在Build Setting中将Debug setting从”DWARF with dSYM File” 改成”DWARF”, Debug setting保持不变。

Web API 集成

DeepShare Web API 提供了一组Web API,可以帮助用户直接通过http访问和在Device端使用DeepShare的相应功能。

注意:请尽量使用Android SDK或者IOS SDK集成,Web API集成复杂度远远大于SDK集成。

添加到工程

请根据您所要调用的Web API的平台做相应修改,以便通过DeepShare链接直接启动App。

Android

修改Manifest.xml,增加DeepShare的intent-filter,这样您的App就可以通过浏览器被唤起。

示例代码如下:

<manifest……>
    <uses-permission android:name="android.permission.INTERNET" />
    <application……>
        <activity……>
            <intent-filter>
                <data
                    android:host="此处填写DashBoard中生成的host"
                    android:scheme="此处填写DashBoard中生成的scheme" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
    </application>
</manifest>

iOS

打开*-Info.plist(*代表你的工程名字),添加用于回调的URL Scheme,App在Dashboard注册后会自动生成此值。

  1. 添加一个叫URL types的键值;
  2. 点击左边剪头打开列表,可以看到Item 0,一个字典实体;
  3. 点击Item 0新增一行,从下拉列表中选择URL Schemes,敲击键盘回车键完成插入;
  4. 更改所插入URL Scheme的值为DashBoard中生成的Scheme。

完成后如图所示:

基本功能

获取场景还原参数

接口协议:

  • URL:https://fds.so/v2/inappdata/用户申请的AppID

  • 请求方式: POST

  • 支持格式: Json

  • 请求参数说明

名称 类型 必填 说明
  is_newuser bool 是否是新安装APP的用户
  unique_id string 用户的唯一识别ID
  sdk_info string 调用方式,其值固定为:"webapi"
  os string 平台标识,其值为"iOS"或者"Android"
  os_version string 平台版本标识,例如:"9.1"(ios)或者"4.4.4"(android)
  model string 安卓设备品牌,例如:"MI 4LTE";IOS不需要此值(android)
  click_id string 老用户打开时,从Scheme URI中解析得出
  short_seg string 老用户打开时, Device是IOS9并且启用Universal Link时,从Universal link中解析得出

  • 返回参数说明
名称 类型 说明
  inapp_data string 所绑定在用户之前点击的DeepShare链接中的场景还原数据

  • 请求Json实例
    1. {"is_newuser" : true, "unique_id" : "320C9F2E-4876-4FD4-A6F5-B3DA804F32C7", "os" : "iOS", "os_version" : "8.1"}
    2. {"is_newuser" : false, "unique_id" : "ce354d4e11c45855", "os" : "Android", "os_version" : "4.4.4", "click_id" : "l8sT0zzTq"}
    3. {"is_newuser" : false, "unique_id" : "320C9F2E-4876-4FD4-A6F5-B3DA804F32C7", "os" : "iOS", "os_version" : "9.1", "short_seg" : "1zXcI3SOvS"}
  • 返回Json实例
    1. {"inapp_data":"{\"key1\":\"value1\"}"}
    2. {"inapp_data":"{\"article_id\":10010,\"has_star\":true,\"author\":\"Hai\"}"}

相关参数详解及参考实现:

  • unique_id: iOS可以用IDFA;Android可以用ANDROID_ID;或者使用用户登录名。当生成DeepShare链接时,此ID需要传入作为sender_id或forwarded_sender_id的参数值。
  • click_id (Android):Android App通过Scheme URI启动时,启动URI格式为<scheme>://<host>?click_id=<click_id>,解析出<click_id>的值。
  /*Android端获取click_id的参考实现*/
    @Override
    public void onStart() {
        Uri data = activity.getIntent().getData();
        if (data != null && data.isHierarchical()) {
            String click_id = data.getQueryParameter("click_id");
            //click_id为对应所需上传参数
        }
    }
 
  • click_id (IOS):Android App通过Scheme URI启动时,启动URI格式为<scheme>://?click_id=<click_id>,解析出<click_id>的值。
 /*IOS端获取click_id的参考实现*/
 + (BOOL)handleURL:(NSURL *)url {
    BOOL handled = NO;
    if (url) {
        NSString *query = [url fragment];
        if (!query) {
            query = [url query];
        }
        handled = YES;
        NSDictionary *params = [DSEncodingUtils decodeQueryStringToDictionary:query];
        if ([params objectForKey:@"click_id"]) {
            NSString *click_id = [params objectForKey:@"click_id"];
            //click_id为对应所需上传参数
        }
    }
    return handled;
}
 
  • short_seg:当iOS9以上版本OS,并启用Universal Link时,iOS App通过Universal Link启动时,启动URI为用户所点击的DeepShare链接,格式为https://fds.so/d/<AppID>/<short_seg>,例如: https://fds.so/d/38CCA4C77072DDC9/1zXcI3SOvS,”1zXcI3SOvS”为其short_seg。
 /*IOS 9 Only*/
 + (BOOL)continueUserActivity:(NSUserActivity *)userActivity {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSString *urlStr = [userActivity.webpageURL absoluteString];
        if(![urlStr containsString:@"fds.so"]){
            return false;
        }
        NSRange range = [urlStr rangeOfString:@"/" options:NSBackwardsSearch];
        if(range.location != NSNotFound) {
            NSString *short_seg = [urlStr substringFromIndex:(range.location + 1)];
            return true;
        } else {
            // wrong url format
            return false;
        }
    }
    return true;
}
 

高级功能

###获取用户分享带来的新的安装量及打开次数

接口协议:

  • URL:https://fds.so/v2/dsusages/用户申请的AppID/分享者senderID

  • 请求方式: GET

  • 返回参数说明

名称 类型 说明
  new_install int 由此分享者所带来的新的APP安装数量
  new_open int 由此分享者所带来的已安装的APP打开的次数

  • 返回Json实例
    1. {"new_install":"1","new_open":"2"}

相关参数详解

  • 分享者senderID: 唯一标识本用户在本App中的分享ID

###清空用户分享带来的新的安装量及打开次数

接口协议:

  • URL:https://fds.so/v2/dsusages/用户申请的AppID/分享者senderID

  • 请求方式: DELETE

相关参数详解

  • 分享者senderID: 唯一标识本用户在本App中的分享ID

Attribution Push 集成

深享系统可以提供App安装后用户事件和流量源头的关联分析。这些事件包括DeepShare内置事件的安装和打开,也包括用户自定义的事件,比如购买、分享。

DeepShare归因分析可以针对渠道或者发送者,其中渠道的归因分析可以通过Web来浏览。而对于基于发生者的归因分析,由于数据量巨大,DeepShare提供自动Push功能,及时的将归因分析的结果Push到开发者提供的后台。

该后台只需要提供一个HTTP/RESTful API,能够接受如下POST:

数据格式

[
    {
        "senderID": "Who is sending the url",
        "tag": "type of action(ds/open, ds/install, or other user defined action)",
        "value": "the amount associated with tag",
    },
    ...
]

Field说明

senderID:DeepShare URL 的生成者ID,此ID就是SDK中的API getSenderId() 的返回值,开发者可以绑定此ID和自己的用户系统。

tag & value:

  • ds/install,表示通过此senderID带来的新安装数量,value为其数量

  • ds/open,表示通过此senderID带来的新打开数量,value为其数量

  • 自定义tag,当分享接收方在SDK中调用attribute(tagToValue, DSFailListener)方法时,其value关联到此tag,归因在其发送方并返回

Universal Link FAQ

Universal Link 生效的场景

iOS9以上设备,生效场景如下表:

应用/浏览器 生效情况
短信 完全支持
邮件 完全支持
微信 分情况
QQ 分情况
微博 分情况
Safari 分情况
Chrome 分情况
Twitter 分情况
Facebook 分情况

分情况:

  1. 直接把DeepShare链接拷贝粘贴到浏览器的地址栏,不会触发Universal Link(打开APP)
  2. 用户在网页中点击链接,如<a href="DeepShareLink">...</a>,会打开APP
  3. 在网页中通过Javascript触发跳转,如(在window.onload或者 通过.click()回调),需要是用户行为触发才能跳转
  4. 在微信、微博、Twitter、Facebook等APP中,只有页面在webview中打开时才会生效,在聊天界面、朋友圈界面、Feed流界面不会打开APP,会在APP内置浏览器中打开网页。通过微信打开分享页面,再在页面中点击DeepShareLink能够触发Universal Link,打开APP

在开发测试时,建议将DeepShare生成的跳转链接拷贝到iOS的短信APP中,以测试Universal Link是否生效,如下图所示

Unilink SMS

直接点击第一个截图中的链接,可以直接跳转APP。跳转到第三个截图,说明Universal Link生效

长按第一个截图中的链接,会出现第二个截图,如果有红圈所示’在***中打开’,说明Universal Link生效,点击可以跳转到第三个截图

Universal Link 没有生效的情况

有些场景不会生效

  1. 在微信聊天界面、QQ聊天界面等,直接点击DeepShare生成的链接,如(https://fds.so/d/78d88b80410c926a/6AgV4wSWBi)不会触发Universal Link,不会直接打开APP
  2. 直接拷贝DeepShare生成的链接,到Safari的地址栏中,不会打开APP,只会在Safari中打开跳转网页

被用户手动禁用

当用通过Universal Link打开APP后,在屏幕右上角会有fds.so,如下图左边第一张截图中红圈所示。当用户点击此处后,会禁用Universal Link,并跳转到下图中间截图的页面。之后,点击DeepShare的链接不会直接打开APP,而是跳到下图中间页面处。在safari中打开下图中间页面,下拉屏幕,可以看到下图最右边的页面,点击打开后,Unversal Link恢复激活状态

Unilink Disable

代码中触发跳转方式错误

由于iOS要求是必须是用户行为触发Universal Link,推荐的跳转方式是: 元素上绑定用户点击事件,当用户点击元素后,触发跳转。

以下两种情况不能触发Universal Link:

  1. 没有用户点击,通过代码自动跳转
  2. 用户点击和触发跳转的时间间隔太长

第二种情况的典型错误例子如下:

var deepShareUrl = null;

var paramsJson = JSON.stringify(params)
$('#openDeepShareUrl').click(function() {
    $.ajax({
        url: 'https://fds.so/v2/url/#appID',
        type: 'POST',
        data: paramsJson,
        xhrFields: {withCredentials: true,},
        success: function(result) {
            // 由于Ajax网络请求会有一定时延,
            // 即,用户点击和执行此跳转有一定时间间隔
            // 会导致不会触发Unversal Link(直接打开APP)
            location.href = result.url
        },
        error: function() {
            //出错情况下可以继续用户正常逻辑,可设置一个默认url.
        },
    });
});

entitlements 文件没有包含在 build target 中

因为一些原因,某些版本的Xcode 7并不会把entitlements file添加到build中,所以我们需要在project browser中手动将新生成的entitlements file添加到正确的target中,这样这个文件才会build。

安装时未激活

iOS只会在APP安装、重装、更新的时候,检查相关配置并激活Universal Link功能。如果所有配置都正确,可以删除重装APP,使Universal Link生效。

简介

一下跳转服务是DeepShare的一项轻量级服务,它通过三行JS代码,简化了开发者从Web页面到App页面跳转的所有问题,自动支持适配Universal link, App Link等系统级跳转功能,并通过跳转数据,帮助开发者优化跳转流程。

注册账号

后台地址为:http://dashboard.deepshare.io

提交注册申请后,请前往注册邮箱,在邮件中点击激活链接,即可进入管理平台

首次登入开发者后台后,可以添加新App, 请按照提示一步一步填写相应信息,完成添加。

添加完成后可以在应用信息中查看并修改之前所添加的所有信息。 其中所生成的AppID作为您的应用在DeepShare的唯一标识,在后继集成环节需要被使用到。

Web端集成

引入DeepShare JS库

在需要调用的页面引入JS库文件 ,其文件地址为:

http://qn.fds.so/deepshare_v2.7.min.js

初始化

初始化DeepShare对象

// 初始化DeepShare, appid为之前后台添加App后所生成的,可以在后台的“应用信息”里查看
var deepshare = new DeepShare('appid');
deepshare.BindParams({});

跳转

将按钮点击事件的回调函数设置为DeepShare的跳转方法start()

deepshare.Start();

完整示例代码如下:

<script type="text/javascript">
// 初始化DeepShare
var deepshare = new DeepShare('38CCA4C77072DDC9');
deepshare.BindParams({});

document.getElementById('#GoToAppButton').addEventListener('click', function() {
    // 触发跳转
    deepshare.Start();
})
</script>

iOS端集成

Universal Link是Apple为iOS 9提供的一个新特性,通过Universal Link,App可以无需打开Safari,直接通过iOS系统启动。

配置developers.apple.com的相关信息

  • 登陆developers.apple.com,点击按钮「Certificate, Identifiers & Profiles」,然后再点击「Identifiers」
  • 确保开启「Associated Domains」,这个按钮在页面下方,如图所示:

配置XCode:

  • 在Xcode配置中开启「Associated Domains」
    1. 选择相应的target;
    2. 点击「Capabilities tab」;
    3. 开启Associated Domains;
    4. 点击「+」按钮,添加一个Associated Domain,其内容为applinks:fds.so。

完成后如图所示:

配置普通浏览器跳转

配置完成后用户可以在Safari中调起App。

  • 修改*-Info.plist(*代表你的工程名字)。
    添加用于回调的URL Scheme,App在Dashboard注册后会自动生成此值
    1. 添加一个叫URL types的键值;
    2. 点击左边剪头打开列表,可以看到Item 0,一个字典实体;
    3. 点击Item 0新增一行,从下拉列表中选择URL Schemes,敲击键盘回车键完成插入;
    4. 更改所插入URL Schemes的值为DashBoard中生成的Scheme。

完成后如图所示:

DashBoard中的iOS Scheme信息:DashBoard>应用信息>iOS应用信息

Android端集成

修改Manifest.xml,在启动Activity中增加DeepShare的intent-filter,这样您的App就可以通过浏览器被唤起

示例代码如下:

<manifest……>
    <uses-permission android:name="android.permission.INTERNET" />
    <application……>
        <activity……>
            <intent-filter>
                <data
                    android:host="此处填写DashBoard中显示的host"
                    android:scheme="此处填写DashBoard中显示的scheme" />
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
    </application>
</manifest>

DashBoard中的Android Scheme信息:DashBoard>应用信息>Android应用信息
(请先填写Package Name, Host通常会和Package Name保持一致)

FAQ

可能有多种原因,请依次排查。

  1. 请确认DashBoard中正确填写了Team Id。
  2. 因为Universal Link是App安装时激活的,如果是从XCode直接Debug版更新安装的,Universal Link可能不会被激活。请完全删除App后重新安装App。
  3. 请确保entitlements file关联了正确的target。因为一些原因,某些版本的Xcode 7并不会把entitlements file添加到build中,所以我们需要在project browser中手动将新生成的entitlements file添加到正确的target中,这样这个文件才会build。