Cordova PhoneGap Ionic
配置 Branch
- Complete your Branch Dashboard


配置应用
- Cordova 和 Ionic
<!-- 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>
-
Change the following values to match your Branch Dashboard
-
com.eneff.branch.cordovatestbed
-
key_live_ndqptlgXNE4LHqIahH1WIpbiyFlb62J3
-
branchcordova
-
cordova.app.link
-
PW4Q8885U7
初始化 Branch
- Cordova 和 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
- Create a deep link from the Branch Dashboard
- 从设备中删除您的应用
- Compile your app (
cordova run ios
phonegap run ios
ionic run ios
) - Paste deep link in Apple Notes
- 长按深度链接(不是 3D Touch)
- Click Open in "APP_NAME" to open your app

测试深度链接 Android
- Create a deep link from the Branch Dashboard
- 从设备中删除您的应用
- Compile your app (
cordova run android
phonegap run android
ionic run android
) - Paste deep link in Google Hangouts
- 点击深度链接打开您的应用
实现功能
初始化 Branch 功能
- 将 Branch 加载到您的应用中
- Must be called on
deviceready
andresume
// 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))
}
})
创建内容参考
- The Branch Universal Object encapsulates the thing you want to share (content or user)
- Uses the Universal Object Properties
// 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))
})
创建深度链接
- 创建带有封装数据的深度链接 URL
- Needs a Branch Universal Object
- Uses Deep Link Properties
- Validate with the Branch Dashboard
// 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))
})
分享深度链接
- 生成 Branch 深度链接,并通过用户选择的渠道对其进行标签
- Needs a Branch Universal Object
- Uses Deep Link Properties
// 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
(to prevent a race condition) - Returns deep link properties
- Listener
// 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))
})
- First data
Branch.getFirstReferringParams().then(function(res) {
alert('Response: ' + JSON.stringify(res))
}).catch(function(err) {
alert('Error: ' + JSON.stringify(err))
})
NativeLink™ Deferred Deep Linking (iOS Only)
- Use iOS pasteboard to enable deferred deep linking via Branch NativeLink™
先决条件
Make sure the underlying iOS SDK Version is v1.39.4+
To use this feature you must:
- Enable NativeLink™ Deep Linking in the Branch Dashboard Configuration tab
or- Manually configure your Branch Link to use
$ios_clipboard_deepview
Implement one of the pasteboard opt-in options in the native iOS SDK code.
Create QR Code
- Set your Qr Code Settings
- Set your Analytics and Link Properties
- Use getBranchQRCode() to create a QR code.
var qrCodeSettings = {
width: 2000,
codeColor: "#3b2016",
backgroundColor: "#a8e689",
centerLogo: "https://cdn.britannica.com/95/156695-131-FF89C9FA/oak-tree.jpg",
margin: 4,
imageFormat: "PNG"
};
var analytics = {
channel: "facebook",
feature: "onboarding",
campaign: "content 123 launch",
stage: "new user",
tags: ["one", "two", "three"],
alias: document.getElementById("alias").value
};
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",
$deeplink_path: "content/123",
$match_duration: 2000,
custom_string: "data",
custom_integer: Date.now(),
custom_boolean: true
};
if (branchUniversalObj === null) {
alert("Need to Generate Branch Universal Object");
return;
}
Branch
.getBranchQRCode(qrCodeSettings, branchUniversalObj, analytics, properties)
.then(function success(res) {
document.getElementById("qrCodeImage").src = "data:image/png;base64, " + res;
})
.catch(function error(err) {
alert(err, true);
});
Learn more from our QR Code API
前往内容
- 在此方法中处理
Branch.initSession()
- Branch 允许您将任何自定义 key-value 从 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));
}
});
展示内容
- List content on iOS Spotlight
- Needs a Branch Universal Object
branchUniversalObj.listOnSpotlight().then(function (res) {
alert('Response: ' + JSON.stringify(res))
}).catch(function (err) {
alert('Error: ' + JSON.stringify(err))
})
追踪内容
- 追踪一段内容的查看次数
- Needs a Branch Universal Object
- Validate with the Branch Dashboard
branchUniversalObj.registerView().then(function (res) {
alert('Response: ' + JSON.stringify(res))
}).catch(function (err) {
alert('Error: ' + JSON.stringify(err))
})
追踪用户
- Sets the identity of a user (ID, UUID, etc) for events, deep links, and referrals
- Validate with the Branch Dashboard
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))
})
追踪事件
- 注册自定义事件
- Events named
open
,close
,install
, andreferred session
are Branch restricted - Best to Track users before Track events to associate a custom event to a user
- Validate with the Branch Dashboard
var eventName = 'clicked_on_this';
var metadata = { 'custom_dictionary': 123, 'anything': 'everything' };
Branch.sendBranchEvent(eventName, metadata);
var eventName = 'clicked_on_this';
Branch.sendBranchEvent(eventName);
追踪 commerce
- 注册自定义 Commerce Event
- Uses Track commerce properties for
Currency
andCategory
- Validate with the Branch Dashboard
Branch.getStandardEvents().then(function success(res) {
var event = res.STANDARD_EVENT_ADD_TO_CART;
var properties = {
transactionID: '12344555',
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"
},
contentMetadata: [
{
"$content_schema": "COMMERCE_PRODUCT",
"$og_title": "Nike Shoe",
"$og_description": "Start loving your steps",
"$og_image_url": "http://example.com/img1.jpg",
"$canonical_identifier": "nike/1234",
"$publicly_indexable": false,
"$price": 101.2,
"$locally_indexable": true,
"$sku": "1101123445",
"$product_name": "Runner",
"$product_brand": "Nike",
"$product_category": "Sporting Goods",
"$product_variant": "XL",
"$creation_timestamp": 1499892854966
},
{
"$content_schema": "COMMERCE_PRODUCT",
"$og_title": "Adidas Shoe",
"$og_description": "Start loving your steps",
"$og_image_url": "http://example.com/img1.jpg",
"$canonical_identifier": "adidas/1234",
"$publicly_indexable": false,
"$price": 90.2,
"$locally_indexable": true,
"$sku": "1101123445",
"$product_name": "Runner",
"$product_brand": "Adidas",
"$product_category": "Sporting Goods",
"$product_variant": "XL",
"$creation_timestamp": 1499892854967
}
],
};
Branch.sendBranchEvent(event, properties);
}).catch(function error(err) {
alert("Get Standard Event " + err);
});
排查问题
测试:Key Points
- Need to select
"app uses IDFA or GAID"
when publishing your app - Best to enable Deepviews (Testing: Supported Platforms)
- Mobile browser capability:
Android 4.4.4+
,Safari 8+
,Chrome 32+
,Firefox 29+
测试:可选的 App Config
- 自定义链接域的附加配置,模拟安装,唯一 Bundle ID 等
<!-- 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">
测试:Branch 分析
- Whenever a user
clicks
on a deep link and opens the app, and will trigger either aninstall
or anopen
installs
代表 Branch 首次识别 app_id 和 device_idinstalls
代表新的应用用户以及您的 Branch 深度链接的成功率installs
不代表 App Store 下载non-Branch installs
为安装在 Branch 深度链接点击之外的opens
为非安装- If a user uninstalls and reinstalls the app, this will be an
open
because Branch recognizes the device - If a user has the app and clicks a Branch deep link, this will be an
open
because the user is not new
测试:模拟安装
- 删除您的应用
- [iOS] iPhone Device->Settings->Privacy->Advertising->Reset Advertising Identifier->Reset Identifier
- [Android] Add
<android-testmode value="true" />
to yourconfig.xml
(Testing: Optional App Config) - 添加
Branch.setDebug(true);
beforeBranch.initSession();
(Initialize Branch Features) - Click on a deep link to navigate to your
$fallback_url
because your app is not installed - 安装您的应用
- 打开您的应用
- Read from
Branch.initSession().then(data)
for+is_first_session = true
测试:支持的平台
- 支持 Branch 深度链接的应用
App | iOS | 细节 | Android | 细节 |
---|---|---|---|---|
Facebook NewsFeed | ✅ | Works when DeepViews are enabled | ✅ | |
Facebook Messenger | ✅ | Works when DeepViews are enabled | ✅ | |
✅ | ✅ | |||
✅ | Works when DeepViews are enabled | ✅ | ||
Slack | ✅ | ✅ | ||
Chrome 地址栏 | 🅾 | 🅾 | ||
Chrome 网页 | ✅ | ✅ | ||
FireFox 地址栏 | 🅾 | 🅾 | ||
FireFox 网页 | ✅ | ✅ | ||
Safar i地址栏 | 🅾 | |||
Safari 网页 | ✅ | |||
✅ | Works when DeepViews are enabled | ✅ | ||
✅ | app.link 要求具有 https/http 已进行点击 | ✅ | app.link requires https/http to be clickable | |
Hangouts | ✅ | ✅ | ||
iMessage | ✅ | |||
苹果邮件 | ✅ | |||
Gmail | ✅ | ✅ |
链接数据:Universal Object 属性
Key | 默认 | 用途 | 链接属性 |
---|---|---|---|
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" or "private" . Public indicates that you’d like this content to be discovered by other apps. | $publicly_indexable |
contentMetadata | 任何自定义键值数据,例如 { "custom": "data" } |
链接数据:深度链接属性
- For Create Deep Link and Share Deep Link
- 分析工具
Key | 默认 | 用途 |
---|---|---|
渠道 | 您可以使用渠道来标记链接到达用户的路径。例如,链接可标记为 "Facebook" or "LinkedIn" to help track clicks and installs through those paths separately | |
功能 | 这是链接可能与您的应用相关的功能。例如,如果您构建了引荐程序,则可以使用 “referral” 功能标记链接 | |
Campaign | 使用此字段按实际 Campaign(营销活动)生成链接。例如,当您启动了一项新功能或产品,并希望围绕该功能设立 Campaign 时,可以使用此功能。 | |
阶段 | 生成链接时,可使用此选项对用户的进度或类别进行分类。例如,如果您的邀请系统可以在1级,3级和5级上访问,则您可以使用此参数来区分在不同级别上生成的链接 | |
标签 | 这是具有无限值的自由格式条目 ["string"] . Use it to organize your link data with labels that don’t fit within the bounds of the above | |
alias | Specify a link alias in place of the standard encoded short URL e.g. yourdomain.com/youralias . Link aliases are unique, immutable objects that cannot be deleted. You cannot change the alias of existing links. Aliases on the legacy bnc.lt domain are incompatible with Universal Links and Spotlight | |
type | 0 | 设置为 1 to limit deep linking behavior of the generated link to a single use. Set type to 2 to make the link show up under Marketing Dashboard while adding $marketing_title to data . Must be an int . Does not work with the Cordova SDK (limitation of native SDKs |
-
属性
- 自定义数据
Key | 值 | 用途 |
---|---|---|
随机 | 123 | key-values 对组 |
你好 | "world" | key-values 对组 |
custom_data | true | key-values 对组 |
- Redirection
Key | 默认 | 用途 |
---|---|---|
$fallback_url | 更改所有平台的重定向 endpoint—因此您不必按平台启用它。需要注意的是 Branch 将所有机器人导向到这个 URL,其中 覆盖任何 OG 标签 中输入的链接。系统范围的默认 URL(在 Link Settings 中设置) | |
$ desktop_url | 更改桌面上 Text-Me-The-App 页面的重定向终结点(在 Link Settings 中设置) | |
$ios_url | 更改您应用的 iOS App Store 页面的重定向终结点(在 Link Settings 中设置) | |
$ipad_url | 更改 iPad 的重定向端点 $ios_url value | |
$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 设备上微信的重定向 endpoint $ios_url value | |
$android_wechat_url | 更改 Android 设备上微信的重定向终结点 $android_url value | |
$after_click_url | 主点击重定向完成后,URL 重定向到 | |
$web_only | false | 强制打开 $fallback_url instead of the app |
- Deep Link
Key | 默认 | 用途 |
---|---|---|
$deeplink_path | open?link_click_id=1234 | 设置所有平台的深度链接路径—因此您不必按平台启用它。当 Branch SDK 收到带有此参数集的链接时,它将自动加载其中包含的自定义 URI 路径 |
$android_deeplink_path | 设置 Android 应用的深度链接路径当 Branch SDK 收到具有此参数集的链接时,它将自动加载包含在其中的自定义 URI 路径 | |
$ios_deeplink_path | 设置 iOS 应用的深度链接路径。当 Branch SDK 收到带有此参数集的链接时,它将自动加载其中包含的自定义 URI 路径 | |
$match_duration | 7200 | 使您可以控制概率建模超时(点击等待应用打开的时间),也称为归因窗口。以秒为单位 |
$always_deeplink | true | 设置为 false to make links always fall back to your mobile site. Does not apply to Universal Links or Android App Links. |
$ios_redirect_timeout | 750 | 控制客户端 JS 在尝试打开应用后重定向到 App Store 之前的等待超时,以毫秒为单位 |
$android_redirect_timeout | 750 | 控制客户端 JS 在尝试打开应用后重定向到 Play Store 之前等待的超时。以毫秒为单位 |
$one_time_use | false | 设置为 true to limit deep linking behavior of the generated link to a single use. Can also be set using type |
$custom_sms_text | 发送给 SMS 链接的文本,供桌面点击此链接。必须包含 {{ link }} Value of Text me the app page in Settings | |
$marketing_title | The Marketing Title for the deep link in the Marketing Dashboard |
- Content
Key | 默认 | 用途 |
---|---|---|
$publicly_indexable | 1 | 无法在此处修改。需要由 Branch Universal Object 设置 |
$keywords | 此内容应作为关键字的关键词。只需使用您想要使用的关键字分配一个 string 数组 | |
$canonical_identifier | 这是内容的标识符,可帮助 Branch 在同一事物的许多实例之间进行重复数据删除。合适的选项:具有路径的网站或具有实体标识符的数据库 | |
$exp_date | 0 | 无法在此处修改。需要由 Branch Universal Object 设置。必须是纪元时间戳,以毫秒为单位 |
$content_type | 这是存在的内容类型的标签。 Apple 建议您按照此处所述使用统一类型的标识符 |
- DeepView
Key | 默认 | 用途 |
---|---|---|
$ios_deepview | default_template | 用于 iOS 的 Deepview 模板的名称 |
$android_deepview | default_template | 用于 Android 的 Deepview 模板的名称 |
$desktop_deepview | default_template | 用于桌面的 Deepview 模板的名称 |
- Open Graph
Key | 默认 | 用途 |
---|---|---|
$og_title | 设置链接的标题,以使其在社交媒体显示中看到 | |
$og_description | 设置链接的描述,以便在社交媒体显示中看到 | |
$og_image_url | 设置链接的图像,使其在社交媒体显示中看到 | |
$og_image_width | 为社交媒体显示设置图像的宽度(以像素为单位) | |
$og_image_height | 设置图像高度(以像素为单位)以显示社交媒体 | |
$og_video | 设置视频,使其在社交媒体显示中看到 | |
$og_url | 设置链接的 base URL,因为它将在社交媒体显示中看到 | |
$og_type | 设置自定义卡格式链接的类型,因为它将在社交媒体显示中看到 | |
$og_redirect | (高级,不建议使用)设置自定义 URL,我们将社交媒体 robot 重定向到该 URL,以便获得所有适当的标签 | | |
$og_app_id | (很少使用)设置应用ID标签 |
- Twitter
Key | 默认 | 用途 |
---|---|---|
$twitter_card | 设置链接的 Twitter 卡类型 | |
$twitter_title | 设置 Twitter 卡的标题 | |
$twitter_description | 设置 Twitter 卡的描述 | |
$twitter_image_url | 设置 Twitter 卡的图片网址 | |
$twitter_site | 设置 Twitter 网站 | |
$twitter_app_country | 设置应用卡的应用国家/地区 | |
$twitter_player | Set the video player’s URL. Defaults to the value of $og_video 。 | |
$twitter_player_width | 设置播放器的宽度(以像素为单位) | |
$twitter_player_height | 设置播放器的高度(以像素为单位) |
链接数据:商业属性
-
For Track commerce
-
分类目录
值 | 类别 | 值 | 类别 |
---|---|---|---|
0 | Animals & Pet Supplies | 11 | Home & Garden |
1 | Apparel & Accessories | 12 | Luggage & Bags |
2 | Arts & Entertainment | 13 | Mature |
3 | Baby & Toddler | 14 | Media |
4 | Business & Industrial | 15 | Office Supplies |
5 | Camera & Optics | 16 | Religious & Ceremonial |
6 | Electronics | 17 | Software |
7 | Food, Beverage & Tobacco | 18 | Sporting Goods |
8 | Furniture | 19 | Toys & Games |
9 | Hardware | 20 | Vehicles & Parts |
10 | Health & Beauty |
- 货币
值 | 货币 | 值 | 货币 | 值 | 货币 |
---|---|---|---|---|---|
0 | AED | 60 | HKD | 120 | RSD |
1 | AFN | 61 | HNL | 121 | RUB |
2 | ALL | 62 | HRK | 122 | RWF |
3 | AMD | 63 | HTG | 123 | SAR |
4 | ANG | 64 | HUF | 124 | SBD |
5 | AOA | 65 | IDR | 125 | SCR |
6 | ARS | 66 | ILS | 126 | SDG |
7 | AUD | 67 | INR | 127 | SEK |
8 | AWG | 68 | IQD | 128 | SGD |
9 | AZN | 69 | IRR | 129 | SHP |
10 | BAM | 70 | ISK | 130 | SLL |
11 | BBD | 71 | JMD | 131 | SOS |
12 | BDT | 72 | JOD | 132 | SRD |
13 | BGN | 73 | JPY | 133 | SSP |
14 | BHD | 74 | KES | 134 | STD |
15 | BIF | 75 | KGS | 135 | SYP |
16 | BMD | 76 | KHR | 136 | SZL |
17 | BND | 77 | KMF | 137 | THB |
18 | BOB | 78 | KPW | 138 | TJS |
19 | BOV | 79 | KRW | 139 | TMT |
20 | BRL | 80 | KWD | 140 | TND |
21 | BSD | 81 | KYD | 141 | TOP |
22 | BTN | 82 | KZT | 142 | TRY |
23 | BWP | 83 | LAK | 143 | TTD |
24 | BYN | 84 | LBP | 144 | TWD |
25 | BYR | 85 | LKR | 145 | TZS |
26 | BZD | 86 | LRD | 146 | UAH |
27 | CAD | 87 | LSL | 147 | UGX |
28 | CDF | 88 | LYD | 148 | USD |
29 | CHE | 89 | MAD | 149 | USN |
30 | CHF | 90 | MDL | 150 | UYI |
31 | CHW | 91 | MGA | 151 | UYU |
32 | CLF | 92 | MKD | 152 | UZS |
33 | CLP | 93 | MMK | 153 | VEF |
34 | CNY | 94 | MNT | 154 | VND |
35 | COP | 95 | MOP | 155 | VUV |
36 | COU | 96 | MRO | 156 | WST |
37 | CRC | 97 | MUR | 157 | XAF |
38 | CUC | 98 | MVR | 158 | XAG |
39 | CUP | 99 | MWK | 159 | XAU |
40 | CVE | 100 | MXN | 160 | XBA |
41 | CZK | 101 | MXV | 161 | XBB |
42 | DJF | 102 | MYR | 162 | XBC |
43 | DKK | 103 | MZN | 163 | XBD |
44 | DOP | 104 | NAD | 164 | XCD |
45 | DZD | 105 | NGN | 165 | XDR |
46 | EGP | 106 | NIO | 166 | XFU |
47 | ERN | 107 | NOK | 167 | XOF |
48 | ETB | 108 | NPR | 168 | XPD |
49 | EUR | 109 | NZD | 169 | XPF |
50 | FJD | 110 | OMR | 170 | XPT |
51 | FKP | 111 | PAB | 171 | XSU |
52 | GBP | 112 | PEN | 172 | XTS |
53 | GEL | 113 | PGK | 173 | XUA |
54 | GHS | 114 | PHP | 174 | XXX |
55 | GIP | 115 | PKR | 175 | YER |
56 | GMD | 116 | PLN | 176 | ZAR |
57 | GNF | 117 | PYG | 177 | ZMW |
58 | GTQ | 118 | QAR | ||
59 | GYD | 119 | RON |
链接数据:Mixpanel 集成
- 如果已安装插件,则与 Mixpanel 同步
Branch.setRequestMetadata("$mixpanel_distinct_id", "123");
编译:Cordova 依赖项
- Node
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)";
brew update;
brew install node;
-
Xcode
- Install Xcode
- 打开 Xcode->同意 SDK 许可协议
- Open Xcode -> Create new Xcode project -> Run simulator -> 在 Mac 上同意运行开发人员模式
-
Android Studio
- Read instructions
- Install JVM
- Install Android Studio
- Open Android Studio -> configure -> appearance/system settings/android sdk -> android 6.0 -> Okay
- Open 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 build-tools 24.0.1
- 生成 Android Keystore
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 [可选]
- Install Virtual Box
- Install 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,因为我们需要插件 hooks 来启用 entitlement,Universal Links,App Links 和 URI scheme 重定向,但是PhoneGap Build 不允许插件 hooks。
-
安装了 “branch-cordova-sdk” 插件和 “cordova-plugin-siri-shortcuts” 插件后,深度链接就会中断。在 Branch 插件之后安装 siri 快捷方式插件时,这似乎最经常发生。
- 解决方案
- Using a modified version of the
AppDelegate+SiriShortcuts
Category to include Branch. This version only works if both Branch and SiriShortcuts is present. - From within the Xcode workspace, locate
AppDelegate+BranchSDK.m
. Either remove it or ignore it. - From within the Xcode workspace, locate
AppDelegate+SiriShortcuts.m
. This is the file we want to modify. - Update
AppDelegate+SiriShortcuts.m
to call Branch SDK. This version should work when dropped in with the current release of both SDKs.
- Using a modified version of the
- 解决方案
#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
-
解决方案
- Fix by opening your app in
Xcode
and launch from there (to select aProvisioning Profile
)
- Fix by opening your app in
无效的 Bundle 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
-
解决方案
- Don't use
cordova
,hyphens
(Android), orunderscores
(iOS) in your bundle id (widget id)
- Don't use
未找到文件
- 错误
Branch.h not found
-
解决方案
-
如果这是您看到的唯一错误,则可以通过升级依赖项来解决。确保您使用的是此插件的4.0.1或更高版本,并且已将 Xcode,Cordova 和其他依赖项(下面列出)更新为最新版本。由于 CocoaPods 和 cordova-ios 无法解决依赖关系而导致的此错误后来被修复。
-
有时,当 Pod 项目中发生构建错误时,就会发生此错误。由于 Branch 通常是按字母顺序排列的第一个 Pod,因此在尝试构建主项目时会显示为错误(因为 Pod 没有被构建),即使真正的错误在其他地方也是如此。确保阅读您的构建日志以查找阻止构建 Pod 项目的原始错误。
-
使用 Pod 构建失败
-
iOS 构建因 Pod 和 CONFIGURATION_BUILD_DIR 配置而失败
-
Command-line builds result in the above error. Please see the section below Compiling: Capacitor for the full list of up-to-date dependencies needed for CLI builds to work.
编译: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)
- Install the plugin cordova-plugin-cocoapods-support
- 该插件不会向您的应用添加任何代码,严格来说,这是在构建应用之前创建Podfile 的 Cordova hooks。
- Add the following lines to the
widget/platform[name="ios"]
path in config.xml:
<preference name="pods_ios_min_version" value="<YOUR MINIMUM VALUE>" />
<pod name="Branch" spec="~> 0.31.3" />
- 更换
<YOUR MINIMUM VALUE>
with the minimum iOS version your app requires, e.g. "8" or "10.0" or "11.4" - 运行
cordova prepare ios
again and ensure you see console output similar to
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.
- Provided that the dependencies listed in the next section are up to date (see Compiling: Capacitor), you should also be able to do
cordova build ios
without issue.
编译:Capacitor
- 该插件的版本4.1.0可与 Ionic 4 + Cordova 和 Ionic 4 + Capacitor 一起使用,但需注意以下几点:
- 我们强烈建议 Node> = 10.15。Note 8可能可用,但未经测试。
- 对于两个 Cordova 和 Capacitor,您必须使用 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
has been removed from this plugin and will now be statically built. If the another podfile usesuse_frameworks
that is fine but this plugin no longer flags itself as dynamic. Ideally your app should be updated to removeuse_frameworks!
from your Podfile.- When using Capacitor, you must add the following entries yourself to
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 的一个局限,其中显式配置更改是开发人员的责任,以避免 “magic config”
- 使用 Capacitor 时,您必须自己通过 Xcode entitlement 编辑器添加 Associated Domain 权限
- 这必须使用 Xcode 完成—这是 Capacitor 核心理念的一部分,您可以控制每个配置文件的更改
- 在 Xcode 中打开 "Signing & Entitlements" 选项卡,添加 Associated Domains entitlement,并添加在 Branch dashboard 上找到的 URL。
AppStore:iOS
- 应用被拒绝,因为它使用推送通知功能,但未声明 aps-environment key
- 当 branch-cordova-sdk 转为使用 CocoaPods 时,Cordova 9 中进行了更改,其中单独的授权文件不再放在一起。通过将 Branch 配置直接添加到您现有的权利中,而不是创建新的权利文件,此插件的版本4.1.0中已解决此问题。此更改与 Cordova 8 向后兼容。
Apple Search Ads:iOS
- Follow the native iOS documentation for setting up Apple Search Ads
Updated 4 months ago