-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added hooks to update android manifest and generate app associate f…
…ile for iOS - Bugfix get params from deep links on iOS - Added Branch framework instead of lib/ lib folders
- Loading branch information
Harsha Bonthu
committed
Mar 11, 2016
1 parent
a30665d
commit 61a4605
Showing
96 changed files
with
1,749 additions
and
7,091 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
Hook executed before the 'prepare' stage. Only for iOS project. | ||
It will check if project name has changed. If so - it will change the name of the .entitlements file to remove that file duplicates. | ||
If file name has no changed - hook would not do anything. | ||
*/ | ||
|
||
var path = require('path'), | ||
fs = require('fs'), | ||
ConfigXmlHelper = require('./lib/configXmlHelper.js'); | ||
|
||
module.exports = function(ctx) { | ||
run(ctx); | ||
}; | ||
|
||
/** | ||
* Run the hook logic. | ||
* | ||
* @param {Object} ctx - cordova context object | ||
*/ | ||
function run(ctx) { | ||
var projectRoot = ctx.opts.projectRoot, | ||
iosProjectFilePath = path.join(projectRoot, 'platforms', 'ios'), | ||
configXmlHelper = new ConfigXmlHelper(ctx), | ||
oldProjectName = getOldProjectName(iosProjectFilePath), | ||
newProjectName = configXmlHelper.getProjectName(); | ||
|
||
// if name has not changed - do nothing | ||
if (oldProjectName.length > 0 && oldProjectName === newProjectName) { | ||
return; | ||
} | ||
|
||
console.log('Project name has changed. Renaming .entitlements file.'); | ||
|
||
// if it does - rename it | ||
var oldEntitlementsFilePath = path.join(iosProjectFilePath, oldProjectName, 'Resources', oldProjectName + '.entitlements'), | ||
newEntitlementsFilePath = path.join(iosProjectFilePath, oldProjectName, 'Resources', newProjectName + '.entitlements'); | ||
|
||
try { | ||
fs.renameSync(oldEntitlementsFilePath, newEntitlementsFilePath); | ||
} catch (err) { | ||
console.warn('Failed to rename .entitlements file.'); | ||
console.warn(err); | ||
} | ||
} | ||
|
||
// region Private API | ||
|
||
/** | ||
* Get old name of the project. | ||
* Name is detected by the name of the .xcodeproj file. | ||
* | ||
* @param {String} projectDir absolute path to ios project directory | ||
* @return {String} old project name | ||
*/ | ||
function getOldProjectName(projectDir) { | ||
var files = [], | ||
projectName = ''; | ||
|
||
try { | ||
files = fs.readdirSync(projectDir); | ||
} catch (err) { | ||
return ''; | ||
} | ||
|
||
// find file with .xcodeproj extension, use it as an old project name | ||
files.some(function(fileName) { | ||
if (path.extname(fileName) === '.xcodeproj') { | ||
projectName = path.basename(fileName, '.xcodeproj'); | ||
return true; | ||
} | ||
|
||
return false; | ||
}); | ||
|
||
return projectName; | ||
} | ||
|
||
// endregion |
Oops, something went wrong.