Cordova PhoneGap Ionic

npmnpm

🚧

iOS 11.2上通用链接行为不一致

将设备更新到iOS 11.2后,我们发现在安装应用程序后,该应用程序的AASA文件不再可靠地下载到您用户的设备上。因此,单击“通用”链接将不再一致地打开该应用程序。您可以在分支链接上设置强制uri重定向模式,以使用URI方案打开应用程序。在Apple Bug报告中查看问题的详细信息。

配置 Branch

图片图片
图片图片

配置应用

  • 科尔多瓦和离子
<!-- sample config.xml -->
    <widget id="com.eneff.branch.cordovatestbed" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
      <!-- Branch -->
      <plugin name="branch-cordova-sdk" spec="^4.0.0" />
      <branch-config>
        <branch-key value="key_live_ndqptlgXNE4LHqIahH1WIpbiyFlb62J3" />
        <uri-scheme value="branchcordova" />
        <link-domain value="cordova.app.link" />  <!-- Required app.link domain -->
        <link-domain value="cordova-alternate.app.link" />  <!-- Required alternate.app.link domain -->
        <ios-team-release value="PW4Q8885U7" />
      </branch-config>
<!-- sample config.xml -->
    <widget id="com.eneff.branch.cordovatestbed" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0">
      <!-- Branch -->
      <plugin name="branch-cordova-sdk" spec="^4.0.0" />
      <branch-config>
        <branch-key value="key_live_ndqptlgXNE4LHqIahH1WIpbiyFlb62J3" />
        <uri-scheme value="branchcordova" />
        <link-domain value="cordova.app.link" />  <!-- Required app.link domain -->
        <link-domain value="cordova-alternate.app.link" />  <!-- Required alternate.app.link domain -->
        <ios-team-release value="PW4Q8885U7" />
      </branch-config>
  • 更改以下值以匹配您的 Branch Dashboard

  • com.eneff.branch.cordovatestbed

  • key_live_ndqptlgXNE4LHqIahH1WIpbiyFlb62J3

  • branchcordova

  • cordova.app.link

  • PW4Q8885U7

初始化 Branch

  • 科尔多瓦和PhoneGap
// sample index.js
    var app = {
      initialize: function() {
        this.bindEvents();
      },
      bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        document.addEventListener('resume', this.onDeviceResume, false);
      },
      onDeviceReady: function() {
        app.handleBranch();
      },
      onDeviceResume: function() {
        app.handleBranch();
      },
      handleBranch: function() {
        // Branch initialization
        Branch.initSession().then(function(data) {
          if (data['+clicked_branch_link']) {
            // read deep link data on click
            alert('Deep Link Data: ' + JSON.stringify(data));
          }
        });
      }
    };

    app.initialize();
// sample app.js
    angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

    .run(function($ionicPlatform) {
      $ionicPlatform.ready(function() {
        if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
          cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
          cordova.plugins.Keyboard.disableScroll(true);
        }
        if (window.StatusBar) {
          StatusBar.styleDefault();
        }

        // Branch
        $ionicPlatform.on('deviceready', function() {
          handleBranch();
        });

        $ionicPlatform.on('resume', function() {
          handleBranch();
        });

        function handleBranch() {
          // Branch initialization
          Branch.initSession().then(function(data) {
            if (data['+clicked_branch_link']) {
              // read deep link data on click
              alert('Deep Link Data: ' + JSON.stringify(data));
            }
          });
        }
      });
    })
    // ...
// sample app.component.js
      import { Component } from '@angular/core';
      import { Platform } from 'ionic-angular';
      import { StatusBar, Splashscreen } from 'ionic-native';

      import { TabsPage } from '../tabs/tabs

      @Component({
        template: `<ion-nav [root]="rootPage"></ion-nav>`
      })
      export class MyApp {
        rootPage = TabsPage;

        constructor(platform: Platform) {
          platform.ready().then(() => {
            StatusBar.styleDefault();
            Splashscreen.hide();
            handleBranch();
          });

          platform.resume.subscribe(() => {
            handleBranch();
          });

          // Branch initialization
          const handleBranch = () => {
            // only on devices
            if (!platform.is('cordova')) { return }
            const Branch = window['Branch'];
            Branch.initSession().then(data => {
              if (data['+clicked_branch_link']) {
                // read deep link data on click
                alert('Deep Link Data: ' + JSON.stringify(data));
              }
            });
          }
        }
      }

测试深层链接iOS

  • Branch 控制面板中创建深度链接

  • 从设备中删除您的应用程序

  • 编译您的应用程序cordova run ios phonegap run ios ionic run ios

  • 粘贴深度链接到 Apple Notes

  • 长按深层链接(不是3D Touch)

  • 点击Open in "APP_NAME"打开您的应用示例

测试深层链接Android

  • Branch 控制面板中创建深度链接

  • 从设备中删除您的应用程序

  • 编译您的应用程序cordova run android phonegap run android ionic run android

  • 粘贴深度链接到 Google Hangouts

  • 点击深层链接打开您的应用

实施功能

初始化分支功能

  • 将Branch加载到您的应用中

  • 必须在devicereadyresume上调用

// for development and debugging only
    Branch.setDebug(true)

    // for GDPR compliance (can be called at anytime)
    Branch.disableTracking(true);

    // Branch initialization
    Branch.initSession().then(function(data) {
      if (data['+clicked_branch_link']) {
        // read deep link data on click
        alert('Deep Link Data: ' + JSON.stringify(data))
      }
    })

创建内容参考

  • 使用 Branch Universal Object 封装您要共享的内容(内容或用户)

  • 使用通用对象属性

// only canonicalIdentifier is required
    var properties = {
      canonicalIdentifier: 'content/123',
      canonicalUrl: 'https://example.com/content/123',
      title: 'Content 123 Title',
      contentDescription: 'Content 123 Description ' + Date.now(),
      contentImageUrl: 'http://lorempixel.com/400/400/',
      price: 12.12,
      currency: 'GBD',
      contentIndexingMode: 'private',
      contentMetadata: {
        custom: 'data',
        testing: 123,
        this_is: true
      }
    }

    // create a branchUniversalObj variable to reference with other Branch methods
    var branchUniversalObj = null
    Branch.createBranchUniversalObject(properties).then(function (res) {
      branchUniversalObj = res
      alert('Response: ' + JSON.stringify(res))
    }).catch(function (err) {
      alert('Error: ' + JSON.stringify(err))
    })

创建深度链接

// optional fields
    var analytics = {
      channel: 'facebook',
      feature: 'onboarding',
      campaign: 'content 123 launch',
      stage: 'new user',
      tags: ['one', 'two', 'three']
    }

    // optional fields
    var properties = {
      $desktop_url: 'http://www.example.com/desktop',
      $android_url: 'http://www.example.com/android',
      $ios_url: 'http://www.example.com/ios',
      $ipad_url: 'http://www.example.com/ipad',
      $match_duration: 2000,
      custom_string: 'data',
      custom_integer: Date.now(),
      custom_boolean: true
    }

    branchUniversalObj.generateShortUrl(analytics, properties).then(function (res) {
      alert('Response: ' + JSON.stringify(res.url))
    }).catch(function (err) {
      alert('Error: ' + JSON.stringify(err))
    })

分享深度链接

// optional fields
    var analytics = {
      channel: 'facebook',
      feature: 'onboarding',
      campaign: 'content 123 launch',
      stage: 'new user',
      tags: ['one', 'two', 'three']
    }

    // optional fields
    var properties = {
      $desktop_url: 'http://www.example.com/desktop',
      custom_string: 'data',
      custom_integer: Date.now(),
      custom_boolean: true
    }

    var message = 'Check out this link'

    // optional listeners (must be called before showShareSheet)
    branchUniversalObj.onShareSheetLaunched(function (res) {
      // android only
      console.log(res)
    })
    branchUniversalObj.onShareSheetDismissed(function (res) {
      console.log(res)
    })
    branchUniversalObj.onLinkShareResponse(function (res) {
      console.log(res)
    })
    branchUniversalObj.onChannelSelected(function (res) {
      // android only
      console.log(res)
    })

    // share sheet
    branchUniversalObj.showShareSheet(analytics, properties, message)

读取深度链接

  • 从深度链接中提取 Branch 数据

  • 最佳做法是从listener 接收数据(以防止出现race condition)

  • 返回深度链接属性

  • 听众

// Branch initialization within your deviceready and resume
    Branch.initSession().then(function success(res) {
      if (res["+clicked_branch_link"]) {
        alert("Open app with a Branch deep link: " + JSON.stringify(res));
        // Branch quick link: https://cordova.app.link/uJcOH1IFpM
        // Branch web link: https://cordova-alternate.app.link/uJcOH1IFpM
        // Branch dynamic link: https://cordova.app.link?tags=one&tags=two&tags=three&channel=Copy&feature=onboarding&stage=new+user&campaign=content+123+launch&type=0&duration=0&source=android&data
        // Branch uri scheme: branchcordova://open?link_click_id=link-500015444967786346
        // Branch android intent: intent://open?link_click_id=518106399270344237#Intent;scheme=looprocks;package=com.eneff.branch.cordovatestbed;S.browser_fallback_url=https%3A%2F%2Fcordova.app.link%2FuJcOH1IFpM%3F__branch_flow_type%3Dchrome_deepview%26__branch_flow_id%3D518106399312287278;S.market_referrer=link_click_id-518106399270344237%26utm_source%3DCopy%26utm_campaign%3Dcontent%20123%20launch%26utm_feature%3Donboarding;S.branch_data=%7B%22~feature%22%3A%22onboarding%22%2C%22this_is%22%3A%22true%22%2C%22custom_string%22%3A%22data%22%2C%22testing%22%3A%22123%22%2C%22%24publicly_indexable%22%3A%22false%22%2C%22%24desktop_url%22%3A%22http%3A%2F%2Fwww.example.com%2Fdesktop%22%2C%22%24one_time_use%22%3Afalse%2C%22custom_object%22%3A%22%7B%5C%5C%5C%22random%5C%5C%5C%22%3A%5C%5C%5C%22dictionary%5C%5C%5C%22%7D%22%2C%22~id%22%3A%22517795540654792902%22%2C%22~campaign%22%3A%22content%20123%20launch%22%2C%22%2Bclick_timestamp%22%3A1524764418%2C%22%2Burl%22%3A%22https%3A%2F%2Fcordova.app.link%2FuJcOH1IFpM%22%2C%22custom_boolean%22%3A%22true%22%2C%22custom%22%3A%22data%22%2C%22source%22%3A%22android%22%2C%22%24og_image_url%22%3A%22http%3A%2F%2Florempixel.com%2F400%2F400%2F%22%2C%22%2Bdomain%22%3A%22cordova.app.link%22%2C%22custom_integer%22%3A%221524690301794%22%2C%22~tags%22%3A%5B%22one%22%2C%22two%22%2C%22three%22%5D%2C%22custom_array%22%3A%22%5B1%2C2%2C3%2C4%2C5%5D%22%2C%22~channel%22%3A%22Copy%22%2C%22~creation_source%22%3A2%2C%22%24canonical_identifier%22%3A%22content%2F123%22%2C%22%24og_title%22%3A%22Content%20123%20Title%22%2C%22%24og_description%22%3A%22Content%20123%20Description%201524690296449%22%2C%22%24identity_id%22%3A%22453670943617990547%22%2C%22~stage%22%3A%22new%20user%22%2C%22%2Bclicked_branch_link%22%3Atrue%2C%22%2Bmatch_guaranteed%22%3Atrue%2C%22%2Bis_first_session%22%3Afalse%7D;B.branch_intent=true;end
        // Branch android app link (device controlled): https://cordova.app.link/uJcOH1IFpM
        // Branch ios universal link (device controlled): https://cordova.app.link/uJcOH1IFpM
      } else if (res["+non_branch_link"]) {
        alert("Open app with a non Branch deep link: " + JSON.stringify(res));
        // Competitor uri scheme: anotherurischeme://hello=world
      } else {
        alert("Open app organically");
        // Clicking on app icon or push notification
      }
    })
    .catch(function error(err) {
      logger(err, true);
    });
  • 最新数据
Branch.getLatestReferringParams().then(function(res) {
  alert('Response: ' + JSON.stringify(res))
}).catch(function(err) {
  alert('Error: ' + JSON.stringify(err))
})
  • 第一数据
Branch.getFirstReferringParams().then(function(res) {
  alert('Response: ' + JSON.stringify(res))
}).catch(function(err) {
  alert('Error: ' + JSON.stringify(err))
})

导航至内容

  • 在内部处理 Branch.initSession()

  • 分支允许您将任何自定义键值从URL传递到您的应用程序。使用此数据导航到内容,显示个性化的欢迎屏幕,登录用户,提供促销等。

Branch.initSession().then(function(data) {
      if (data['+clicked_branch_link']) {
        // option 1: save to model to be used later
        window.localStorage['branchData'] = data;

        // option 2: navigate to page
        window.location.href = '#/content/123'

        // option 3: display data
        alert(JSON.stringify(data));
      }
    });

展示内容

branchUniversalObj.listOnSpotlight().then(function (res) {
  alert('Response: ' + JSON.stringify(res))
}).catch(function (err) {
  alert('Error: ' + JSON.stringify(err))
})

跟踪内容

branchUniversalObj.registerView().then(function (res) {
  alert('Response: ' + JSON.stringify(res))
}).catch(function (err) {
  alert('Error: ' + JSON.stringify(err))
})

跟踪用户

  • 设置事件、深度链接和推荐的用户标识(电子邮件、ID 和 UUID 等)

  • 使用 Branch 控制面板进行验证

var userId = '123456'
    Branch.setIdentity(userId).then(function (res) {
      alert('Response: ' + JSON.stringify(res))
    }).catch(function (err) {
      alert('Error: ' + JSON.stringify(err.message))
    })
  • 删除用户身份
Branch.logout().then(function (res) {
      alert('Response: ' + JSON.stringify(res))
    }).catch(function (err) {
      alert('Error: ' + JSON.stringify(err.message))
    })

径赛项目

var eventName = 'clicked_on_this';
var metadata = { 'custom_dictionary': 123, 'anything': 'everything' };
Branch.sendBranchEvent(eventName, metadata);

var eventName = 'clicked_on_this';
Branch.sendBranchEvent(eventName);

追踪贸易

Branch.getStandardEvents().then(function success(res) {
  var event = res.STANDARD_EVENT_ADD_TO_CART;
  var metadata = {
    customerEventAlias: 'alias name for event',
    transactionID: '1234455',
    currency: 'USD',
    revenue: 1.5,
    shipping: 10.2,
    tax: 12.3,
    coupon: 'test_coupon',
    affiliation: 'test_affiliation',
    description: 'Test add to cart event',
    searchQuery: 'test keyword',
    customData: {
      "Custom_Event_Property_Key1": "Custom_Event_Property_val1",
      "Custom_Event_Property_Key2": "Custom_Event_Property_val2"
    }
  };
  Branch.sendBranchEvent(event, metadata);
}).catch(function error(err) {
  alert("Get Standard Event " + err);
});

处理推荐(referral)

var amount = 10;
var bucket = "this_bucket";
Branch.redeemRewards(amount, bucket).then(function success(res) {
  alert("Response: " + JSON.stringify(res));
}).catch(function error(err) {
  alert("Error: " + JSON.stringify(err));
});

var amount = 10;
Branch.redeemRewards(amount).then(function success(res) {
  alert("Response: " + JSON.stringify(res));
}).catch(function error(err) {
  alert("Error: " + JSON.stringify(err));
});
  • 负荷积分
var bucket = "this_bucket";
Branch.loadRewards(bucket).then(function success(res) {
  alert("Response: " + JSON.stringify(res));
}).catch(function error(err) {
  alert("Error: " + JSON.stringify(err));
});

Branch.loadRewards().then(function success(res) {
  alert("Response: " + JSON.stringify(res));
}).catch(function error(err) {
  alert("Error: " + JSON.stringify(err));
});
  • 载入记录
Branch.creditHistory().then(function success(res) {
  alert("Response: " + JSON.stringify(res));
}).catch(function error(err) {
  alert("Error: " + JSON.stringify(err));
});

解决问题

测试:重点

  • 发布应用时需要选择"app uses IDFA or GAID"

  • 最好启用Deepviews测试:支持的平台

  • 移动浏览器功能: Android 4.4.4+Safari 8+Chrome 32+Firefox 29+

测试:可选的App Config

  • 自定义链接域的附加配置,模拟安装,唯一的捆绑包标识符等
<!-- sample config.xml -->
    <widget id="com.eneff.branch.cordovatestbed" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
      <!-- Branch -->
      <plugin name="branch-cordova-sdk" spec="^4.0.0" /> <!-- optional spec -->
      <branch-config>
        <branch-key value="key_live_ndqptlgXNE4LHqIahH1WIpbiyFlb62J3" />
        <uri-scheme value="branchcordova" />
        <link-domain value="yourcustomdomain.com" />
        <link-domain value="cordova.app.link" />  <!-- optional previous link domain -->
        <link-domain value="bnc.lt" />  <!-- optional previous link domain -->
        <ios-team-release value="PW4Q8885U7" /> <!-- required if iOS app -->
        <ios-team-debug value="FG35JLLMXX" /> <!-- optional -->
        <android-prefix value="/WSuf" /> <!-- optional (for bnc.lt) -->
        <android-testmode value="true" /> <!-- optional (simulate installs) -->
      </branch-config>
      
      
 <widget ios-CFBundleIdentifier="com.eneff.branch.cordovatestbedios" android-packageName="com.eneff.branch.cordovatestbedandroid" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">

测试:分支分析

  • 每当用户clicks使用深层链接并打开应用程序时,就会触发installopen

  • installs 代表Branch首次识别app_id和device_id

  • installs 代表新的应用程序用户以及您的分支机构深层链接的成功率

  • installs 不代表应用商店下载

  • non-Branch installs 是安装在分支机构深层链接点击之外的

  • opens 是非安装

  • 如果用户卸载并重新安装该应用程序,则它将是open因为Branch会识别该设备

  • 如果用户拥有该应用程序并单击“分支”深层链接,则该名称为open因为该用户不是新用户

测试:模拟安装

  • 删除您的应用

  • [iOS] iPhone设备->设置->隐私->广告->重置广告标识符->重置标识符

  • [Android]<android-testmode value="true" />添加到您的config.xml测试:可选的App Config

  • Branch.initSession(); 之前添加Branch.setDebug(true);在初始化Branch之前

  • 点击深度链接接导航到您的$fallback_url ,因为您的应用尚未安装

  • 安装您的应用

  • 打开你的应用

  • Branch.initSession().then(data)读取+is_first_session = true

测试:支持的平台

  • 支持分支深层链接的应用
iOS细节安卓细节
Facebook NewsFeed启用DeepViews后有效
脸书Messanger启用DeepViews后有效
Twitter
Pinterest启用DeepViews后有效
Slack
Chrome地址栏🅾🅾
Chrome网页
FireFox地址栏🅾🅾
FireFox网页
Safari地址栏🅾
Safari网页
微信启用DeepViews后有效
WhatsApp的app.link 要求可点击https / httpapp.link 要求可点击https / http
环聊
iMessage的
苹果邮件
Gmail邮箱

链接数据:通用对象属性

默认用途链接属性
canonicalIdentifier (必需) 这是内容的唯一标识,将帮助 Branch 在同一事物的许多实例之间进行重复数据删除。合适的选项:具有路径的网站或具有实体唯一标识的数据库$canonical_identifier
canonicalUrl规范网址,用于SEO$canonical_url
title内容的名称$og_title
contentDescription内容说明$og_description
contentImageUrl内容的图片网址。必须是绝对路径$og_image_url
price商品价格$amount
currency表示价格的货币,采用ISO 4217货币代码$currency
contentIndexingMode"public"可以设置为"public""private" 。公开表示您希望此内容被其他应用发现。$publicly_indexable
contentMetadata任何自定义键值数据,例如 { "custom": "data" }

链接数据:深度链接属性

默认用途
渠道您可以使用渠道来标记链接到达用户的路径。例如,带有"Facebook""LinkedIn" 标记的链接可分别追踪点击和安装
特征这是链接可能与您的应用程序相关的功能。例如,如果您构建了引荐程序,则可以使用“引荐”功能标记链接
广告系列使用此字段按实际 Campaign(营销活动)生成链接。例如,当您启动了一项新功能或产品,并希望围绕该功能设立 Campaign 时,可以使用此功能。
阶段生成链接时,可使用此选项对用户的进度或类别进行分类。例如,如果您的邀请系统可以在1级,3级和5级上访问,则您可以使用此参数来区分在不同级别上生成的链接
标记这是具有不受限制的值["string"]的自由格式条目。用它来组织链接数据,其标签不属于上述范围
别名指定链接别名代替标准编码的短URL,例如yourdomain.com/youralias 。链接别名是无法删除的唯一,不可变的对象。您不能更改现有链接的别名。旧版bnc.lt域上的别名与通用链接和Spotlight不兼容
类型0设置为1可以将生成的链接的深层链接行为限制为一次性使用。将type设置为2可使链接显示在Marketing Dashboard下,同时将$marketing_title添加到data 。必须为int 。不适用于Cordova SDK(本机SDK的限制)
  • 属性

    • 自订资料
用途
随机123key-values 对组
你好"world"key-values 对组
custom_datatruekey-values 对组
- Redirection
默认用途
$fallback_url更改所有平台的重定向端点-因此您不必按平台启用它。需要注意的是分公司将所有机器人转发到这个URL,其中 覆盖任何OG标签 中的链接进入。系统范围的默认URL(在“链接设置”中设置)
$ desktop_url更改桌面上 Text-Me-The-App 页面的重定向终结点(在 Link Settings 中设置)
$ios_url更改您应用程序的 iOS App Store 页面的重定向终结点(在 Link Settings 中设置)
$ipad_url更改 iPad $ios_url 的重定向端点
$android_url更改您应用的 Android Play 商店页面的重定向端点(在 Link Settings 中设置)
$windows_phone_url更改 Windows 操作系统和手机的默认 URL 重定向终结点(在 Link Setting 中设置)
$blackberry_url更改 Blackberry OS BlackBerry 默认URL的重定向终结点(在 Link Setting 中设置)
$fire_url更改 Amazon Fire OS Fire 默认 URL 的重定向终端节点(在 Link Setting 中设置)
$ios_wechat_url更改iOS设备上微信的重定向终结点 $ios_url value
$android_wechat_url更改 Android 设备上微信的重定向终结点$android_url
$ after_click_url主点击重定向完成后,URL重定向到
$ web_onlyfalse强制打开 $fallback_url 并非应用程序
- Deep Link
默认用途
$deeplink_pathopen?link_click_id=1234设置所有平台的深层链接路径-因此您不必按平台启用它。当Branch SDK收到带有此参数集的链接时,它将自动加载其中包含的自定义URI路径
$android_deeplink_path设置Android应用程序的深层链接路径当Branch SDK收到具有此参数集的链接时,它将自动加载包含在其中的自定义URI路径
$ios_deeplink_path设置iOS应用的深层链接路径。当Branch SDK收到带有此参数集的链接时,它将自动加载其中包含的自定义URI路径
$ match_duration7200使您可以控制概率建模超时(单击等待应用程序打开的时间),也称为归因窗口。以秒为单位
$ always_deeplinktrue设置为false 可使链接始终回退到您的移动网站。不适用于 Universal Links 或 Android App Links。
$ ios_redirect_timeout750控制客户端 JS 在尝试打开应用程序后重定向到 App Store 之前的等待超时,以毫秒为单位
$ android_redirect_timeout750控制客户端JS在尝试打开应用程序后重定向到Play商店之前等待的超时。以毫秒为单位
$one_time_usefalse设置为true可以将生成的链接的深层链接行为限制为一次性使用。也可以使用类型设置
$ custom_sms_text发送给SMS链接的文本,供桌面点击此链接。 “设置”中的应用页面必须包含{{ link }} “ Text me me”值
$ marketing_title行销资讯主页深层连结的行销标题
- Content
默认用途
$publicly_indexable1无法在此处修改。需要由 Branch Universal Object 设置
$关键字此内容应作为关键字的关键词。只需使用您想要使用的关键字分配一个字符串数组
$canonical_identifier这是内容的唯一标识,可帮助 Branch 在同一事物的许多实例之间进行重复数据删除。合适的选项:具有路径的网站或具有实体唯一标识的数据库
$ exp_date0无法在此处修改。需要由“分支通用对象”设置。必须是纪元时间戳,以毫秒为单位
$ content_type这是存在的内容类型的标签。 Apple 建议您按照此处所述使用统一类型的唯一标识
- DeepView
默认用途
$ios_deepviewdefault_template用于iOS的Deepview模板的名称
$android_deepviewdefault_template用于Android的Deepview模板的名称
$desktop_deepviewdefault_template用于桌面的Deepview模板的名称
- Open Graph
默认用途
$og_title设置链接的标题,以使其在社交媒体显示中看到
$ og_description设置链接的描述,以便在社交媒体显示中看到
$og_image_url设置链接的图像,使其在社交媒体显示中看到
$ og_image_width为社交媒体显示设置图像的宽度(以像素为单位)
$ og_image_height设置图像高度(以像素为单位)以显示社交媒体
$og_video设置视频,使其在社交媒体显示中看到
$og_url设置链接的基本URL,因为它将在社交媒体显示中看到
$ og_type设置自定义卡格式链接的类型,因为它将在社交媒体显示中看到
$ og_redirect(高级,不建议使用)设置自定义URL,我们将社交媒体机器人重定向到该URL,以便检索所有适当的标签
$ og_app_id(很少使用)设置应用程序ID标签
- Twitter
默认用途
$ twitter_card设置链接的Twitter卡类型
$ twitter_title设置Twitter卡的标题
$ twitter_description设置Twitter卡的描述
$twitter_image_url设置Twitter卡的图片网址
$ twitter_site设置Twitter网站
$ twitter_app_country设置应用卡的应用国家/地区
$ twitter_player设置视频播放器的URL。缺省值为$og_video
$ twitter_player_width设置播放器的宽度(以像素为单位)
$ twitter_player_height设置播放器的高度(以像素为单位)

链接数据:商业属性

类别类别
0Animals & Pet Supplies11Home & Garden
1Apparel & Accessories12Luggage & Bags
2Arts & Entertainment13Mature
3Baby & Toddler14Media
4Business & Industrial15Office Supplies
5Camera & Optics16Religious & Ceremonial
6Electronics17Software
7Food, Beverage & Tobacco18Sporting Goods
8Furniture19Toys & Games
9Hardware20Vehicles & Parts
10Health & Beauty
  • 货币
货币货币货币
0AED60HKD120RSD
1AFN61HNL121RUB
2ALL62HRK122RWF
3AMD63HTG123SAR
4ANG64HUF124SBD
5AOA65IDR125SCR
6ARS66ILS126SDG
7AUD67INR127SEK
8AWG68IQD128SGD
9AZN69IRR129SHP
10BAM70ISK130SLL
11BBD71JMD131SOS
12BDT72JOD132SRD
13BGN73JPY133SSP
14BHD74KES134STD
15BIF75KGS135SYP
16BMD76KHR136SZL
17BND77KMF137THB
18BOB78KPW138TJS
19BOV79KRW139TMT
20BRL80KWD140TND
21BSD81KYD141TOP
22BTN82KZT142TRY
23BWP83LAK143TTD
24BYN84LBP144TWD
25BYR85LKR145TZS
26BZD86LRD146UAH
27CAD87LSL147UGX
28CDF88LYD148USD
29CHE89MAD149USN
30CHF90MDL150UYI
31CHW91MGA151UYU
32CLF92MKD152UZS
33CLP93MMK153VEF
34CNY94MNT154VND
35COP95MOP155VUV
36COU96MRO156WST
37CRC97MUR157XAF
38CUC98MVR158XAG
39CUP99MWK159XAU
40CVE100MXN160XBA
41CZK101MXV161XBB
42DJF102MYR162XBC
43DKK103MZN163XBD
44DOP104NAD164XCD
45DZD105NGN165XDR
46EGP106NIO166XFU
47ERN107NOK167XOF
48ETB108NPR168XPD
49EUR109NZD169XPF
50FJD110OMR170XPT
51FKP111PAB171XSU
52GBP112PEN172XTS
53GEL113PGK173XUA
54GHS114PHP174XXX
55GIP115PKR175YER
56GMD116PLN176ZAR
57GNF117PYG177ZMW
58GTQ118QAR
59GYD119RON

链接数据:Mixpanel集成

  • 如果已安装插件,则与Mixpanel同步
Branch.setRequestMetadata("$mixpanel_distinct_id", "123");

编译:Cordova依赖项

  • 节点
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)";
brew update;
brew install node;
  • Xcode

    • 安装Xcode

    • 打开Xcode->同意SDK许可协议

    • 打开Xcode->创建新的Xcode项目->运行模拟器->在Mac上同意开发人员模式

  • Android Studio

    • 阅读说明

    • 安装JVM

    • 安装Android Studio

    • 打开Android Studio-> configure -> appearance/system settings/android sdk -> android 6.0 -> Okay

    • 打开Android Studio-> New project -> ... -> Run -> Create new emulator -> Nexus 6p 23 -> Finish

# add to ~/.bash_profile
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH


source ~/.bash_profile;


android update sdk;
  • 安装Android SDK构建工具24.0.1

  • 生成Android密钥库

keytool -genkeypair -dname "cn=Full Name, ou=Business Unit, o=Company, c=US" -alias release -keypass aaa111 -keystore release.keystore -storepass aaa111 -validity 10000
keytool -list -v -keystore release.keystore
  • Genymotion [可选]

    • 安装虚拟盒子

    • 安装Genymotion

    • Genymotion-> Add virtual device -> Google Nexus 6P - 6.0.0 - API 23 -> Next

编译:显示控制台日志

  • iOS模拟器

    • cordova run ios;

    • Safari-> Preferences -> Advance -> Show Develop menu in menu bar

    • Safari-> Develop -> Simulator -> index.html -> Console

    • 可能需要拔出并重新插入设备

    • 可能需要打开Xcode并更新配置文件

  • iOS Xcode

    • cordova plugin add cordova-plugin-console;

    • cordova build ios;

    • Xcode-> APP_LOCATION/platforms/ios/APP_NAME.Xcodeproj

    • Xcode-> App -> General -> Signing -> Team

    • Xcode-> Product -> Run

    • Xcode-> View -> Debug Area -> Activate Console

  • Android设备

    • 插入设备

    • cordova run android;

    • Chrome-> [chrome://inspect/#devices](chrome://inspect/#devices) -> Console

  • Android Genymotion

    • Genymotion-> Start

    • cordova run android;

    • Chrome-> [chrome://inspect/#devices](chrome://inspect/#devices) -> Console

编译:更新Branch SDK

  • 获得最新的改进和功能
# terminal
cordova plugin remove io.branch.sdk
cordova plugin remove branch-cordova-sdk
<!-- config.xml -->
<plugin name="branch-cordova-sdk" spec="^4.0.0" />

编译:不兼容

  • 以下插件不适用于Branch SDK

  • Branch SDK也不支持PhoneGap Build,因为我们需要插件挂钩来启用权利,通用链接,应用程序链接和URI方案重定向,但是PhoneGap Build不允许插件挂钩。

  • 安装了“ branch-cordova-sdk”插件和“ cordova-plugin-siri-shortcuts”插件后,深层链接就会中断。在分支插件之后安装siri快捷方式插件时,这似乎最经常发生。

      • 使用AppDelegate+SiriShortcuts类别的修改版本来包含Branch。仅当存在Branch和SiriShortcuts时,此版本才有效。
      • 在Xcode工作空间中,找到AppDelegate+BranchSDK.m 。删除它或忽略它。
      • 在Xcode工作空间中,找到AppDelegate+SiriShortcuts.m 。这是我们要修改的文件。
      • 更新AppDelegate+SiriShortcuts.m以调用Branch SDK。当两个SDK的当前版本一起使用时,此版本应该可用。
#import "AppDelegate+SiriShortcuts.h"
    #import <objectivec/runtime.h>

    #import "BranchNPM.h"

    #ifdef BRANCH_NPM
    #import "Branch.h"
    #else
    #import <Branch/Branch.h>
    #endif

    static void * UserActivityPropertyKey = &UserActivityPropertyKey;

    @implementation AppDelegate (siriShortcuts)

    - (NSUserActivity *)userActivity {
        return objectivec_getAssociatedObject(self, UserActivityPropertyKey);
    }

    - (void)setUserActivity:(NSUserActivity *)activity {
        objectivec_setAssociatedObject(self, UserActivityPropertyKey, activity, objectivec_ASSOCIATION_RETAIN_NONATOMIC);
    }

    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {

        // SiriShortcuts code
        NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
        if ([userActivity.activityType isEqualToString:[NSString stringWithFormat:@"%@.shortcut", bundleIdentifier]]) {
            self.userActivity = userActivity;
        }

        // Respond to Universal Links
        if (![[Branch getInstance] continueUserActivity:userActivity]) {
            // send unhandled URL to notification
            if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
                [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"BSDKPostUnhandledURL" object:[userActivity.webpageURL absoluteString]]];
            }
        }

        return YES;
    }

    // Respond to URI scheme links
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
        // pass the url to the handle deep link call
        if (![[Branch getInstance] application:app openURL:url options:options]) {
            // do other deep link routing for the Facebook SDK, Pinterest SDK, etc
            [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
            // send unhandled URL to notification
            [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"BSDKPostUnhandledURL" object:[url absoluteString]]];
        }
        return YES;
    }

    // Respond to Push Notifications
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
        @try {
            [[Branch getInstance] handlePushNotification:userInfo];
        }
        @catch (NSException *exception) {
            [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"BSDKPostUnhandledURL" object:userInfo]];
        }
    }

    @end

编译:Cordova错误

从SDK 2.5+迁移到3.0+

// Branch initialization
- Branch.initSession(function(data) {
+ Branch.initSession().then(function(data) {
if (data["+clicked_branch_link"]) {
// read deep link data on click
alert("Deep Link Data: " + JSON.stringify(data));
}
});

仅设备

  • 错误

ORIGINAL EXCEPTION: Branch is not defined

ReferenceError: Branch is not defined

    • Branch将打开并安装您的应用程序,因此您无法在桌面浏览器或模拟器中模拟Branch
// Ionic 2/3 - running on browser instead of device
if (!platform.is('cordova')) { return }
Branch.userCompletedAction('did_this')


// Ionic 2/3 - missing Branch import
const Branch = window['Branch'];

配给配置文件丢失

  • 错误

** ARCHIVE FAILED **

The following build commands failed:
Check dependencies
    (1 failure)
    Error: Error code 65 for command: xcodebuild with args: -xcconfig,cordova/build-debug.xcconfig,-workspace,Branch Testing.xcworkspace,-scheme,Branch Testing,-configuration,Debug,-destination,generic/platform=iOS,-archivePath,Branch Testing.xcarchive,archive,CONFIGURATION_BUILD_DIR=build/device,SHARED_PRECOMPS_DIR=build/sharedpch
No profiles for 'com.eneff.branch.cordova_testbed' were found
    • 通过在Xcode打开应用并从那里启动(选择Provisioning Profile )进行修复

无效的捆绑商品ID

  • 错误
An invalid value 'XC com eneff branch cordova_testbed' was provided for the parameter 'appIdName'.


Error: Error code 1 for command: /gradlew with args: cdvBuildDebug,-b,/build.gradle,-Dorg.gradle.daemon=true,-Pandroid.useDeprecatedNdk=true
    • 捆绑包ID(小部件ID)中请勿使用cordovahyphens (Android)或underscores (iOS)

文件未找到

  • 错误
Branch.h not found
    • 如果这是您看到的唯一错误,则可以通过升级依赖项来解决。确保您使用的是此插件的4.0.1或更高版本,并且已将Xcode,Cordova和其他依赖项(下面列出)更新为最新版本。由于CocoaPods和cordova-ios无法解决依赖关系而导致的此错误后来被修复。

    • 有时,当Pod项目中发生构建错误时,就会发生此错误。由于Branch通常是按字母顺序排列的第一个Pod,因此在尝试构建主项目时会显示为错误(因为Pod没有被构建),即使真正的错误在其他地方也是如此。确保阅读您的构建日志以查找阻止构建Pod项目的原始错误。

使用Pod构建失败

  • iOS构建因Pod和CONFIGURATION_BUILD_DIR配置而失败

  • 命令行生成会导致上述错误。请参阅“编译:电容器”下面的部分,以获取CLI构建正常工作所需的最新依赖关系的完整列表。

编译:Cordova 8

  • 该插件的版本4.1.x与Cordova 8兼容,但是您需要在config.xml文件中添加一些字段:

  • Cordova 8不正确支持CocoaPods,此插件的4.x版本利用了CocoaPods。

  • 此插件不能同时包含两个版本的Pod规范(在Cordova 8和Cordova 9之间进行了更改)。我们选择包含Cordova 9版本。

  • 为了支持Cordova 8对CocoaPods的处理,您必须安装一个额外的Cordova插件以正确合并我们的CocoaPod(从2020.02.10开始的“ Branch” v.0.31.3)

  • 安装插件cordova-plugin-cocoapods-support

  • 该插件不会向您的应用程序添加任何代码,严格来说,这是在构建应用程序之前创建Podfile的Cordova钩子。

  • 将以下行添加到config.xml中的widget/platform[name="ios"]路径:

<preference name="pods_ios_min_version" value="<YOUR MINIMUM VALUE>" />
<pod name="Branch" spec="~> 0.31.3" />
  • <YOUR MINIMUM VALUE>替换为您的应用所需的最低iOS版本,例如“ 8”或“ 10.0”或“ 11.4”

  • 再次运行cordova prepare ios并确保您看到类似于以下内容的控制台输出

Searching for new pods
Checking config.xml for pods.
config.xml requires pod: Branch
Installing pods
Sit back and relax this could take a while.
  • 如果下一节中列出的依赖关系是最新的(请参见编译:电容器),那么您也应该能够进行cordova build ios而不会有任何问题。

编译:电容器

  • 该插件的版本4.1.0可与Ionic 4 + Cordova和Ionic 4 + Capacitor一起使用,但有以下警告:

  • 我们强烈建议Node> = 10.15。节点8可能工作,但未经测试。

  • 对于两个Cordova和电容器,您必须使用Xcode> = 11.1,CocoaPods> = 1.8.4,Cordova> = 8.0.0,Ionic-CLI> = 5.1,cordova-ios> = 5.1.0

    • 这些依赖项中的每一个都有可用于命令行构建的修补程序,并且pod依赖项解析可以正常工作
  • 您必须使用@ capacitor / ios> = 1.4.0。该版本之前的版本未将OpenURL通知与其他插件(包括Branch)联合。

  • use_frameworks 已从此插件中删除,现在将以静态方式构建。如果另一个Podfile使用use_frameworks很好,但是此插件不再将其自身标记为动态。理想情况下,应更新您的应用以从Podfile中删除use_frameworks!

  • 使用电容器时,必须将以下条目自己添加到ios/App/App/Info.plist

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLName</key>
    <string>com.getcapacitor.capacitor</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>capacitor</string>
    </array>
  </dict>
  <dict>
    <key>CFBundleURLName</key>
    <string>branch-cordova-sdk</string>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>[YOUR URL SCHEME HERE]</string>
    </array>
  </dict>
</array>
<key>branch_key</key>
<string>[YOUR BRANCH LIVE KEY]</string>
<key>branch_app_domain</key>
<string>[YOUR DOMAIN].app.link</string>
  • 这是Capacitor的一个局限,其中显式配置更改是开发人员的责任,以避免“魔术配置”

  • 使用电容器时,您必须自己通过Xcode权利编辑器添加关联域权利

    • 这必须使用Xcode完成-再次,这是Capacitor核心理念的一部分,您可以控制每个配置文件的更改

    • 在Xcode中打开“签名和权利”选项卡,添加“关联的域”权利,并添加在“分支”仪表板上找到的URL。

AppStore:iOS

  • 应用被拒绝,因为它使用推送通知功能,但未声明aps-environment密钥

  • 当branch-cordova-sdk转为使用CocoaPods时,Cordova 9中进行了更改,其中单独的授权文件不再放在一起。通过将分支配置直接添加到您现有的权利中,而不是创建新的权利文件,此插件的版本4.1.0中已解决此问题。此更改与Cordova 8向后兼容。

Apple搜索广告:iOS

4个月前更新


Cordova PhoneGap Ionic


建议的编辑仅限于API参考页

您只能建议对Markdown正文内容进行修改,而不能建议对API规范进行修改。