Skip to content

Commit cdb891f

Browse files
committed
Merge pull request #66 from harshabonthu/master
Bugfix for iOS missing params in deeplinks and Android applinks
2 parents 51b77d2 + 0e824d0 commit cdb891f

File tree

96 files changed

+1763
-7109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1763
-7109
lines changed

README.md

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,42 @@ There's a full demo app embedded in this repository. It should serve as an examp
2525

2626
**Install parameters:**
2727
* `BRANCH_LIVE_KEY` - Your Branch live API key. You can sign up for your own Branch key at [https://dashboard.branch.io](https://dashboard.branch.io).
28+
* `BRANCH_TEST_KEY` - Your Branch test API key. You can sign up for your own Branch key at [https://dashboard.branch.io](https://dashboard.branch.io).
2829
* `URI_SCHEME` - It could be your app name or the URI set in your Branch dashboard. As a reminder, the URI scheme is what you use to open your app from a browser, i.e. `yourapp://`.
29-
* [optional] `ENCODED_ID` - This is for supporting App Links (6.0+) on Android. You can obtain the encodied id from the Branch dashboard. Just append `--variable ENCODED_ID=your-encoded-id` to the plugin install command below. For more info about App Links, please see [this](https://github.com/BranchMetrics/Android-Deferred-Deep-Linking-SDK/blob/master/README.md#leverage-android-app-links-for-deep-linking) section of the Android readme.
30+
* [optional] `ENCODED_ID` - This is for supporting App Links (6.0+) on Android. You can obtain the encodied id from the Branch dashboard. For more info about App Links, please see [this](https://github.com/BranchMetrics/Android-Deferred-Deep-Linking-SDK/blob/master/README.md#leverage-android-app-links-for-deep-linking) section of the Android readme.
3031

3132
#### Cordova
3233

3334
```sh
34-
cordova plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=<your-branch-key> --variable URI_SCHEME=<your-app-uri-scheme-without-colon-and-slashes>
35+
cordova plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=<your-branch-key> --variable BRANCH_TEST_KEY=<your-branch-key> --variable URI_SCHEME=<your-app-uri-scheme-without-colon-and-slashes>
3536
```
3637
example:
3738
```sh
38-
cordova plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable URI_SCHEME=branchsters
39+
cordova plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable BRANCH_LIVE_KEY=key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc --variable URI_SCHEME=branchsters
3940
```
4041

4142
#### Phonegap
4243

4344
```sh
44-
phonegap plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=your-branch-key --variable URI_SCHEME=your-app-uri-scheme --variable ENCODED_ID=your-encoded-id
45+
phonegap plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=your-branch-key --variable BRANCH_TEST_KEY=your-branch-key --variable URI_SCHEME=your-app-uri-scheme --variable ENCODED_ID=your-encoded-id
4546
```
4647

4748
example:
4849
```sh
49-
phonegap plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable URI_SCHEME=branchsters
50+
phonegap plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable BRANCH_LIVE_KEY=key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc --variable URI_SCHEME=branchsters
5051
```
5152

5253
#### NPM
5354

5455
**Note** NPM is still running the old repository for module v 1.8. Please see [the documentation here](https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK/tree/v1.8.0-locked).
5556

5657
```sh
57-
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=your-branch-key --variable URI_SCHEME=your-app-uri-scheme --variable ENCODED_ID=your-encoded-id
58+
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=your-branch-key --variable BRANCH_TEST_KEY=your-branch-key --variable URI_SCHEME=your-app-uri-scheme
5859
```
5960

6061
example:
6162
```sh
62-
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable URI_SCHEME=branchsters
63+
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable BRANCH_LIVE_KEY=key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc --variable URI_SCHEME=branchsters
6364
```
6465

6566
### Additional App Permissions
@@ -74,23 +75,17 @@ In iOS 9.2, Apple dropped support for URI scheme redirects. You must enable Univ
7475

7576
1. enable `Associated Domains` capability on the Apple Developer portal when you create your app's bundle identifier.
7677
2. In your [Dashboard Link Settings](https://dashboard.branch.io/#/settings/link), tick the `Enable Universal Links` checkbox and provide the Bundle Identifier and Apple Team ID in the appropriate boxes.
77-
3. Finally, add `associated-domains` to your entitlements file. Since cordova doesn't have a way to a create entitlements and associate it to your generated project, we
78-
will generate the said file with the help of [Cordova Universal Links Plugin](https://github.com/nordnet/cordova-universal-links-plugin), a third plarty plugin.
78+
`
7979

80-
**Note:** The purpose of the said plugin is to generate an entitlements file and associate it to your generated project. No other implementations from the plugin are need as this guide will cover what only needs to be implemented.
81-
82-
To start, go to your project root and install the plugin:
83-
84-
```sh
85-
cordova plugin add cordova-universal-links-plugin
86-
```
87-
88-
After the installation, add the following entry to your application's `config.xml`:
80+
Add the following entry to your application's `config.xml`:
8981

9082
```xml
9183
<universal-links>
92-
<ios-team-id value=your_ios_team_id />
93-
<host name="bnc.lt">
84+
<ios-team-id value="your_ios_team_id" />
85+
<host name="bnc.lt" scheme="https">
86+
<path prefix="your_encoded_id"/>
87+
<!--optional test ENV encoded id-->
88+
<path prefix="/your_encoded_id"/>
9489
</host>
9590
</universal-links>
9691
```

hooks/afterPrepareHook.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
Hook is executed at the end of the 'prepare' stage. Usually, when you call 'cordova build'.
3+
4+
It will inject required preferences in the platform-specific projects, based on <universal-links>
5+
data you have specified in the projects config.xml file.
6+
*/
7+
8+
var configParser = require('./lib/configXmlParser.js'),
9+
androidManifestWriter = require('./lib/android/manifestWriter.js'),
10+
// androidWebHook = require('./lib/android/webSiteHook.js'),
11+
iosProjectEntitlements = require('./lib/ios/projectEntitlements.js'),
12+
// iosAppSiteAssociationFile = require('./lib/ios/appleAppSiteAssociationFile.js'),
13+
iosProjectPreferences = require('./lib/ios/xcodePreferences.js'),
14+
ANDROID = 'android',
15+
IOS = 'ios';
16+
17+
module.exports = function(ctx) {
18+
run(ctx);
19+
};
20+
21+
/**
22+
* Execute hook.
23+
*
24+
* @param {Object} cordovaContext - cordova context object
25+
*/
26+
function run(cordovaContext) {
27+
var pluginPreferences = configParser.readPreferences(cordovaContext),
28+
platformsList = cordovaContext.opts.platforms;
29+
30+
// if no preferences are found - exit
31+
if (pluginPreferences == null) {
32+
return;
33+
}
34+
35+
// if no host is defined - exit
36+
if (pluginPreferences.hosts == null || pluginPreferences.hosts.length == 0) {
37+
console.warn('No host is specified in the config.xml. Universal Links plugin is not going to work.');
38+
return;
39+
}
40+
41+
platformsList.forEach(function(platform) {
42+
switch (platform) {
43+
case ANDROID:
44+
{
45+
activateUniversalLinksInAndroid(cordovaContext, pluginPreferences);
46+
break;
47+
}
48+
case IOS:
49+
{
50+
activateUniversalLinksInIos(cordovaContext, pluginPreferences);
51+
break;
52+
}
53+
}
54+
});
55+
}
56+
57+
/**
58+
* Activate Deep Links for Android application.
59+
*
60+
* @param {Object} cordovaContext - cordova context object
61+
* @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from <universal-links> tag.
62+
*/
63+
function activateUniversalLinksInAndroid(cordovaContext, pluginPreferences) {
64+
// inject preferenes into AndroidManifest.xml
65+
androidManifestWriter.writePreferences(cordovaContext, pluginPreferences);
66+
67+
// generate html file with the <link> tags that you should inject on the website.
68+
// androidWebHook.generate(cordovaContext, pluginPreferences);
69+
}
70+
71+
/**
72+
* Activate Universal Links for iOS application.
73+
*
74+
* @param {Object} cordovaContext - cordova context object
75+
* @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from <universal-links> tag.
76+
*/
77+
function activateUniversalLinksInIos(cordovaContext, pluginPreferences) {
78+
// modify xcode project preferences
79+
iosProjectPreferences.enableAssociativeDomainsCapability(cordovaContext);
80+
81+
// generate entitlements file
82+
iosProjectEntitlements.generateAssociatedDomainsEntitlements(cordovaContext, pluginPreferences);
83+
84+
// generate apple-site-association-file
85+
// iosAppSiteAssociationFile.generate(cordovaContext, pluginPreferences);
86+
}

hooks/beforePluginInstallHook.js

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/**
2+
Hook is executed when plugin is added to the project.
3+
It will check all necessary module dependencies and install the missing ones locally.
4+
*/
5+
6+
var exec = require('child_process').exec,
7+
path = require('path'),
8+
fs = require('fs'),
9+
INSTALLATION_FLAG_FILE_NAME = '.installed';
10+
11+
// region NPM specific
12+
13+
/**
14+
* Check if node package is installed.
15+
*
16+
* @param {String} moduleName
17+
* @return {Boolean} true if package already installed
18+
*/
19+
function isNodeModuleInstalled(moduleName) {
20+
var installed = true;
21+
try {
22+
var module = require(moduleName);
23+
} catch (err) {
24+
installed = false;
25+
}
26+
27+
return installed;
28+
}
29+
30+
/**
31+
* Install node module locally.
32+
* Basically, it runs 'npm install module_name'.
33+
*
34+
* @param {String} moduleName
35+
* @param {Callback(error)} callback
36+
*/
37+
function installNodeModule(moduleName, callback) {
38+
if (isNodeModuleInstalled(moduleName)) {
39+
printLog('Node module ' + moduleName + ' is found');
40+
callback(null);
41+
return;
42+
}
43+
printLog('Can\'t find module ' + moduleName + ', running npm install');
44+
45+
var cmd = 'npm install -D ' + moduleName;
46+
exec(cmd, function(err, stdout, stderr) {
47+
callback(err);
48+
});
49+
}
50+
51+
/**
52+
* Install all required node packages.
53+
*/
54+
function installRequiredNodeModules(modulesToInstall) {
55+
if (!modulesToInstall.length) {
56+
return;
57+
}
58+
59+
var moduleName = modulesToInstall.shift();
60+
installNodeModule(moduleName, function(err) {
61+
if (err) {
62+
printLog('Failed to install module ' + moduleName + ':' + err);
63+
return;
64+
}
65+
66+
printLog('Module ' + moduleName + ' is installed');
67+
installRequiredNodeModules(modulesToInstall);
68+
});
69+
}
70+
71+
// endregion
72+
73+
// region Logging
74+
75+
function logStart() {
76+
console.log('Checking dependencies:');
77+
}
78+
79+
function printLog(msg) {
80+
var formattedMsg = ' ' + msg;
81+
console.log(formattedMsg);
82+
}
83+
84+
// endregion
85+
86+
// region Private API
87+
88+
/**
89+
* Check if we already executed this hook.
90+
*
91+
* @param {Object} ctx - cordova context
92+
* @return {Boolean} true if already executed; otherwise - false
93+
*/
94+
function isInstallationAlreadyPerformed(ctx) {
95+
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME),
96+
isInstalled = false;
97+
try {
98+
var content = fs.readFileSync(pathToInstallFlag);
99+
isInstalled = true;
100+
} catch (err) {
101+
}
102+
103+
return isInstalled;
104+
}
105+
106+
/**
107+
* Create empty file - indicator, that we tried to install dependency modules after installation.
108+
* We have to do that, or this hook is gonna be called on any plugin installation.
109+
*/
110+
function createPluginInstalledFlag(ctx) {
111+
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME);
112+
113+
fs.closeSync(fs.openSync(pathToInstallFlag, 'w'));
114+
}
115+
116+
// endregion
117+
118+
/**
119+
* Read dependencies from the package.json.
120+
* We will install them on the next step.
121+
*
122+
* @param {Object} ctx - cordova context
123+
* @return {Array} list of modules to install
124+
*/
125+
function readDependenciesFromPackageJson(ctx) {
126+
var data = require(path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, 'package.json')),
127+
dependencies = data['dependencies'],
128+
modules = [];
129+
130+
if (!dependencies) {
131+
return modules;
132+
}
133+
134+
for (var module in dependencies) {
135+
modules.push(module);
136+
}
137+
138+
return modules;
139+
}
140+
141+
// hook's entry point
142+
module.exports = function(ctx) {
143+
// exit if we already executed this hook once
144+
if (isInstallationAlreadyPerformed(ctx)) {
145+
return;
146+
}
147+
148+
logStart();
149+
150+
var modules = readDependenciesFromPackageJson(ctx);
151+
installRequiredNodeModules(modules);
152+
153+
createPluginInstalledFlag(ctx);
154+
};

0 commit comments

Comments
 (0)