Skip to content

Commit

Permalink
Merge branch 'master' into feat/added-unit-testing
Browse files Browse the repository at this point in the history
# Conflicts:
#	testbed/config.xml
#	testbed/init.sh
  • Loading branch information
aaustin committed Mar 12, 2016
2 parents 3e83aaa + f6c44af commit 27cb561
Show file tree
Hide file tree
Showing 98 changed files with 1,780 additions and 7,042 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ testbed/plugins
testbed/hooks
node_modules
testbed/ul_web_hooks/
.installed
39 changes: 16 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,45 +21,44 @@ There's a full demo app embedded in this repository. It should serve as an examp
**The compiled iOS SDK footprint is 180kb**
**The compiled Android SDK footprint is 187kb**

### Command link install
### Command link install

**Install parameters:**
* `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).
* `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).
* `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://`.
* [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.
* [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.

#### Cordova

```sh
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>
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>
```
example:
```sh
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
cordova plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_fnmRM1FXtu11t6e4LU8WsldpvDcA0bzv --variable BRANCH_TEST_KEY=key_test_oicIH5u2yxW9w3i6UZdfCiokyrixWpBJ --variable URI_SCHEME=branchsters
```

#### Phonegap

```sh
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
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
```

example:
```sh
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
phonegap plugin add https://github.com/BranchMetrics/Cordova-Ionic-PhoneGap-Deferred-Deep-Linking-SDK.git --variable BRANCH_LIVE_KEY=key_live_fnmRM1FXtu11t6e4LU8WsldpvDcA0bzv --variable BRANCH_TEST_KEY=key_test_oicIH5u2yxW9w3i6UZdfCiokyrixWpBJ --variable URI_SCHEME=branchsters
```

#### NPM

**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).

```sh
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
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
```

example:
```sh
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=key_live_gchnKkd3l3m9YBPP2d73jmfejkcgVjgM --variable URI_SCHEME=branchsters
npm install branch-cordova-sdk --variable BRANCH_LIVE_KEY=key_live_fnmRM1FXtu11t6e4LU8WsldpvDcA0bzv --variable BRANCH_TEST_KEY=key_test_oicIH5u2yxW9w3i6UZdfCiokyrixWpBJ --variable URI_SCHEME=branchsters
```

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

1. enable `Associated Domains` capability on the Apple Developer portal when you create your app's bundle identifier.
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.
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
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.

**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.

To start, go to your project root and install the plugin:

```sh
cordova plugin add cordova-universal-links-plugin
```
`

After the installation, add the following entry to your application's `config.xml`:
Add the following entry to your application's `config.xml`:

```xml
<universal-links>
<ios-team-id value=your_ios_team_id />
<host name="bnc.lt">
<ios-team-id value="your_ios_team_id" />
<host name="bnc.lt" scheme="https">
<path prefix="/your_encoded_id" />
<!--optional test ENV encoded id-->
<path prefix="/your_encoded_id" />
</host>
</universal-links>
```
Expand Down
86 changes: 86 additions & 0 deletions hooks/afterPrepareHook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
Hook is executed at the end of the 'prepare' stage. Usually, when you call 'cordova build'.
It will inject required preferences in the platform-specific projects, based on <universal-links>
data you have specified in the projects config.xml file.
*/

var configParser = require('./lib/configXmlParser.js'),
androidManifestWriter = require('./lib/android/manifestWriter.js'),
// androidWebHook = require('./lib/android/webSiteHook.js'),
iosProjectEntitlements = require('./lib/ios/projectEntitlements.js'),
// iosAppSiteAssociationFile = require('./lib/ios/appleAppSiteAssociationFile.js'),
iosProjectPreferences = require('./lib/ios/xcodePreferences.js'),
ANDROID = 'android',
IOS = 'ios';

module.exports = function(ctx) {
run(ctx);
};

/**
* Execute hook.
*
* @param {Object} cordovaContext - cordova context object
*/
function run(cordovaContext) {
var pluginPreferences = configParser.readPreferences(cordovaContext),
platformsList = cordovaContext.opts.platforms;

// if no preferences are found - exit
if (pluginPreferences == null) {
return;
}

// if no host is defined - exit
if (pluginPreferences.hosts == null || pluginPreferences.hosts.length == 0) {
console.warn('No host is specified in the config.xml. Universal Links plugin is not going to work.');
return;
}

platformsList.forEach(function(platform) {
switch (platform) {
case ANDROID:
{
activateUniversalLinksInAndroid(cordovaContext, pluginPreferences);
break;
}
case IOS:
{
activateUniversalLinksInIos(cordovaContext, pluginPreferences);
break;
}
}
});
}

/**
* Activate Deep Links for Android application.
*
* @param {Object} cordovaContext - cordova context object
* @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from <universal-links> tag.
*/
function activateUniversalLinksInAndroid(cordovaContext, pluginPreferences) {
// inject preferenes into AndroidManifest.xml
androidManifestWriter.writePreferences(cordovaContext, pluginPreferences);

// generate html file with the <link> tags that you should inject on the website.
// androidWebHook.generate(cordovaContext, pluginPreferences);
}

/**
* Activate Universal Links for iOS application.
*
* @param {Object} cordovaContext - cordova context object
* @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from <universal-links> tag.
*/
function activateUniversalLinksInIos(cordovaContext, pluginPreferences) {
// modify xcode project preferences
iosProjectPreferences.enableAssociativeDomainsCapability(cordovaContext);

// generate entitlements file
iosProjectEntitlements.generateAssociatedDomainsEntitlements(cordovaContext, pluginPreferences);

// generate apple-site-association-file
// iosAppSiteAssociationFile.generate(cordovaContext, pluginPreferences);
}
154 changes: 154 additions & 0 deletions hooks/beforePluginInstallHook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
Hook is executed when plugin is added to the project.
It will check all necessary module dependencies and install the missing ones locally.
*/

var exec = require('child_process').exec,
path = require('path'),
fs = require('fs'),
INSTALLATION_FLAG_FILE_NAME = '.installed';

// region NPM specific

/**
* Check if node package is installed.
*
* @param {String} moduleName
* @return {Boolean} true if package already installed
*/
function isNodeModuleInstalled(moduleName) {
var installed = true;
try {
var module = require(moduleName);
} catch (err) {
installed = false;
}

return installed;
}

/**
* Install node module locally.
* Basically, it runs 'npm install module_name'.
*
* @param {String} moduleName
* @param {Callback(error)} callback
*/
function installNodeModule(moduleName, callback) {
if (isNodeModuleInstalled(moduleName)) {
printLog('Node module ' + moduleName + ' is found');
callback(null);
return;
}
printLog('Can\'t find module ' + moduleName + ', running npm install');

var cmd = 'npm install -D ' + moduleName;
exec(cmd, function(err, stdout, stderr) {
callback(err);
});
}

/**
* Install all required node packages.
*/
function installRequiredNodeModules(modulesToInstall) {
if (!modulesToInstall.length) {
return;
}

var moduleName = modulesToInstall.shift();
installNodeModule(moduleName, function(err) {
if (err) {
printLog('Failed to install module ' + moduleName + ':' + err);
return;
}

printLog('Module ' + moduleName + ' is installed');
installRequiredNodeModules(modulesToInstall);
});
}

// endregion

// region Logging

function logStart() {
console.log('Checking dependencies:');
}

function printLog(msg) {
var formattedMsg = ' ' + msg;
console.log(formattedMsg);
}

// endregion

// region Private API

/**
* Check if we already executed this hook.
*
* @param {Object} ctx - cordova context
* @return {Boolean} true if already executed; otherwise - false
*/
function isInstallationAlreadyPerformed(ctx) {
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME),
isInstalled = false;
try {
var content = fs.readFileSync(pathToInstallFlag);
isInstalled = true;
} catch (err) {
}

return isInstalled;
}

/**
* Create empty file - indicator, that we tried to install dependency modules after installation.
* We have to do that, or this hook is gonna be called on any plugin installation.
*/
function createPluginInstalledFlag(ctx) {
var pathToInstallFlag = path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, INSTALLATION_FLAG_FILE_NAME);

fs.closeSync(fs.openSync(pathToInstallFlag, 'w'));
}

// endregion

/**
* Read dependencies from the package.json.
* We will install them on the next step.
*
* @param {Object} ctx - cordova context
* @return {Array} list of modules to install
*/
function readDependenciesFromPackageJson(ctx) {
var data = require(path.join(ctx.opts.projectRoot, 'plugins', ctx.opts.plugin.id, 'package.json')),
dependencies = data['dependencies'],
modules = [];

if (!dependencies) {
return modules;
}

for (var module in dependencies) {
modules.push(module);
}

return modules;
}

// hook's entry point
module.exports = function(ctx) {
// exit if we already executed this hook once
if (isInstallationAlreadyPerformed(ctx)) {
return;
}

logStart();

var modules = readDependenciesFromPackageJson(ctx);
installRequiredNodeModules(modules);

createPluginInstalledFlag(ctx);
};
Loading

0 comments on commit 27cb561

Please sign in to comment.