Skip to content

Instantly share code, notes, and snippets.

@LinusU
Forked from apla/icons_and_splash.js
Last active July 17, 2021 08:06
Show Gist options
  • Save LinusU/7515016 to your computer and use it in GitHub Desktop.
Save LinusU/7515016 to your computer and use it in GitHub Desktop.
Icons and Splash images for your Cordova project. (with iOS 7 support)

Usage

Install cordova into node_modules

npm install cordova

Add icons_and_splash.js

Copy icons_and_splash.js into the .cordova/hooks/after_prepare directory.

It also needs to be executable: chmod +x .cordova/hooks/after_prepare/icons_and_splash.js

Add this to your config.xml

<icon src="res/icons/" />

Add these files to your www directory

www/res
`-- icons
    |-- android
    |   |-- icon-36-ldpi.png
    |   |-- icon-48-mdpi.png
    |   |-- icon-72-hdpi.png
    |   `-- icon-96-xhdpi.png
    `-- ios
        |-- icon-29-2x.png
        |-- icon-29.png
        |-- icon-40-2x.png
        |-- icon-40.png
        |-- icon-50-2x.png
        |-- icon-50.png
        |-- icon-57-2x.png
        |-- icon-57.png
        |-- icon-60-2x.png
        |-- icon-60.png
        |-- icon-72-2x.png
        |-- icon-72.png
        |-- icon-76-2x.png
        `-- icon-76.png

Report any error

If you get any error, please report error in comments here. I will then try to fix and update this gist accordingly. Please help us take away the pain in adding a custom icon to our applications.

#
# (Windows)
#
# What is this?
#
# It's a shell script that is using ImageMagick to create all the icon files from one source icon.
#
# If you'd like to use it on windows install ImageMagick:
# http://www.imagemagick.org/script/binary-releases.php#windows
#
# Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Command Prompt.
#
mkdir android
convert my-hires-icon.png -resize 36x36 android/icon-36-ldpi.png
convert my-hires-icon.png -resize 48x48 android/icon-48-mdpi.png
convert my-hires-icon.png -resize 72x72 android/icon-72-hdpi.png
convert my-hires-icon.png -resize 96x96 android/icon-96-xhdpi.png
mkdir ios
convert my-hires-icon.png -resize 29 ios/icon-29.png
convert my-hires-icon.png -resize 40 ios/icon-40.png
convert my-hires-icon.png -resize 50 ios/icon-50.png
convert my-hires-icon.png -resize 57 ios/icon-57.png
convert my-hires-icon.png -resize 58 ios/icon-29-2x.png
convert my-hires-icon.png -resize 60 ios/icon-60.png
convert my-hires-icon.png -resize 72 ios/icon-72.png
convert my-hires-icon.png -resize 76 ios/icon-76.png
convert my-hires-icon.png -resize 80 ios/icon-40-2x.png
convert my-hires-icon.png -resize 100 ios/icon-50-2x.png
convert my-hires-icon.png -resize 114 ios/icon-57-2x.png
convert my-hires-icon.png -resize 120 ios/icon-60-2x.png
convert my-hires-icon.png -resize 144 ios/icon-72-2x.png
convert my-hires-icon.png -resize 152 ios/icon-76-2x.png
#
# (OS X, Unix and Linux)
#
# What is this?
#
# It's a shell script that is using ImageMagick to create all the icon files from one source icon.
#
# Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Terminal.
#
ICON=${1:-"my-hires-icon.png"}
mkdir android
convert $ICON -resize 36x36 android/icon-36-ldpi.png
convert $ICON -resize 48x48 android/icon-48-mdpi.png
convert $ICON -resize 72x72 android/icon-72-hdpi.png
convert $ICON -resize 96x96 android/icon-96-xhdpi.png
mkdir ios
convert $ICON -resize 29 ios/icon-29.png
convert $ICON -resize 40 ios/icon-40.png
convert $ICON -resize 50 ios/icon-50.png
convert $ICON -resize 57 ios/icon-57.png
convert $ICON -resize 58 ios/icon-29-2x.png
convert $ICON -resize 60 ios/icon-60.png
convert $ICON -resize 72 ios/icon-72.png
convert $ICON -resize 76 ios/icon-76.png
convert $ICON -resize 80 ios/icon-40-2x.png
convert $ICON -resize 100 ios/icon-50-2x.png
convert $ICON -resize 114 ios/icon-57-2x.png
convert $ICON -resize 120 ios/icon-60-2x.png
convert $ICON -resize 144 ios/icon-72-2x.png
convert $ICON -resize 152 ios/icon-76-2x.png
#!/usr/bin/env node
var cordova_util = require('cordova/src/util');
var projectRoot = cordova_util.isCordova(process.cwd());
var projectXml = cordova_util.projectConfig(projectRoot);
var projectConfig = new cordova_util.config_parser(projectXml);
var projectPlatforms = cordova_util.listPlatforms(projectRoot);
projectConfig.name();
var fs = require ('fs');
var platformDir = {
ios: {
icon: "{$projectName}/Resources/icons",
splash: "{$projectName}/Resources/splash",
nameMap: {
// iOS >= 7 Settings icon
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPhone
"icon-29.png": "icon-small.png",
"icon-29-2x.png": "icon-small@2x.png",
// iOS >= 7 Spotlight search results icon (recommended)
"icon-40.png": "icon-40.png",
"icon-40-2x.png": "icon-40@2x.png",
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPad
"icon-50.png": "icon-50.png",
"icon-50-2x.png": "icon-50@2x.png",
// iOS <= 6.1 App icon (required) iPhone
"icon-57.png": "icon.png",
"icon-57-2x.png": "icon@2x.png",
// iOS >= 7 App icon (required) iPhone
"icon-60.png": "icon-60.png",
"icon-60-2x.png": "icon-60@2x.png",
// iOS <= 6.1 App icon (required) iPad
"icon-72.png": "icon-72.png",
"icon-72-2x.png": "icon-72@2x.png",
// iOS 7 App icon (required) iPad
"icon-76.png": "icon-76.png",
"icon-76-2x.png": "icon-76@2x.png",
// "screen-iphone-landscape.png": "Default~iphone.png",
"screen-ipad-portrait.png": "Default-Portrait~ipad.png",
"screen-ipad-portrait-2x.png": "Default-Portrait@2x~ipad.png",
"screen-ipad-landscape-2x.png": "Default-Landscape@2x~ipad.png",
"screen-ipad-landscape.png": "Default-Landscape~ipad.png",
"screen-iphone-portrait.png": "Default~iphone.png",
"screen-iphone-portrait-2x.png": "Default@2x~iphone.png",
"screen-iphone-portrait-568h-2x.png": "Default-568h@2x~iphone.png"
}
},
android: {
icon:"res/drawable-{$density}",
splash:"res/drawable-{$density}",
nameMap: {
"icon-36-ldpi.png": "icon.png",
"icon-48-mdpi.png": "icon.png",
"icon-72-hdpi.png": "icon.png",
"icon-96-xhdpi.png": "icon.png",
"screen-ldpi-portrait.png": "ic_launcher.png",
"screen-mdpi-portrait.png": "ic_launcher.png",
"screen-hdpi-portrait.png": "ic_launcher.png",
"screen-xhdpi-portrait.png": "ic_launcher.png"
}
},
blackberry10: {},
wp7: {},
wp8: {}
}
function copyAsset (scope, node) {
var platform = node.attrib['gap:platform'];
var density = node.attrib['gap:density'];
var assetDirTmpl = platformDir[platform] && platformDir[platform][scope];
if (!assetDirTmpl) {
throw new Error('Platform and density not supported: ' + platform + ', ' + density);
}
var dict = {
projectName: projectConfig.name(),
density: density
};
var assetDir = assetDirTmpl.replace(/{\$([^}]+)}/, function (match, p1) {
return dict[p1];
});
var srcPath = 'www/'+node.attrib.src;
var fileName = srcPath.match(/[^\/]+$/)[0];
if (platformDir[platform] && platformDir[platform].nameMap && platformDir[platform].nameMap[fileName]) {
fileName = platformDir[platform].nameMap[fileName];
} else {
throw new Error('Unknown icon name for platform ' + platform);
}
var dstPath = 'platforms/'+platform+'/'+assetDir+'/'+fileName;
console.log ('copying from '+srcPath+' to the '+dstPath);
// so, here we start to copy asset
fs.stat (srcPath, function (err, stats) {
if (err) {
throw err;
}
var r = fs.createReadStream(srcPath);
r.on ('open', function () {
r.pause();
var w = fs.createWriteStream(dstPath);
w.on ('open', function () {
r.pipe(w);
r.resume();
});
w.on ('error', function() {
throw new Error('Cannot write file');
})
});
r.on ('error', function() {
throw new Error('Cannot read file');
});
});
}
projectConfig.doc.findall('icon').map(function (node) {
if (/\/$/.test(node.attrib['src']) && node.attrib['gap:platform'] === undefined && node.attrib['gap:density'] === undefined) {
if (~projectPlatforms.indexOf('android')) {
// Android
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-36-ldpi.png', 'gap:density': 'ldpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-48-mdpi.png', 'gap:density': 'mdpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-72-hdpi.png', 'gap:density': 'hdpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-96-xhdpi.png', 'gap:density': 'xhdpi' } });
}
if (~projectPlatforms.indexOf('ios')) {
// iOS >= 7 Settings icon
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-29.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-29-2x.png' } });
// iOS >= 7 Spotlight search results icon (recommended)
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-40.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-40-2x.png' } });
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-50.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-50-2x.png' } });
// iOS <= 6.1 App icon (required) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-57.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-57-2x.png' } });
// iOS >= 7 App icon (required) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-60.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-60-2x.png' } });
// iOS <= 6.1 App icon (required) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-72.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-72-2x.png' } });
// iOS 7 App icon (required) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-76.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-76-2x.png' } });
}
} else {
copyAsset ('icon', node);
}
});
projectConfig.doc.findall('*').filter(function (node) {
return (node.tag == 'gap:splash');
}).map(function (node) {
copyAsset ('splash', node);
});
@jshbrntt
Copy link

Works great but what baffles me is why I even need this script on 3.3.0-0.1.1 when in the docs it appears this should work without it?

Also for any novices wondering what that 'convert.sh' file is:

It's a shell script that appears to be using ImageMagick to creating all the icon files from a source icon.

If you'd like to use it on windows install ImageMagick:
http://www.imagemagick.org/script/binary-releases.php#windows

Then you should be able to use the same script by renaming it from 'convert.sh' to 'convert.bat'.

Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Command Prompt.

@unexist
Copy link

unexist commented Dec 17, 2013

Thanks for the nice script, there is one typo though:

throw new Error('Platform and densite not supported: ' + platform + ', ' + density);

Should be 'density' and not 'densite'. ;)

Edit: I'd also suggest to replace the errors with console output, because a default config includes icon/splash definitions for every supported platform.

@numediaweb
Copy link

What I couldn't understand is the cordova docs; one time they say to put the images in www/res/icons directory (www/res/screens subdirectory for splash), then they say something different in the same page ; platforms/android/res/drawable* directories :( could somebody explaine why should I put the icons in two different folders?
Thanks

@LinusU
Copy link
Author

LinusU commented Dec 31, 2013

(Sorry for late reply, didn't get any notifications...)

@slaskis The script dosen't have proper support yet but this should work:

<gap:platform gap:platform="ios" src="res/splash/ios/screen-iphone-portrait.png" />

The following files work for iOS:

screen-ipad-portrait.png
screen-ipad-portrait-2x.png 
screen-ipad-landscape-2x.png
screen-ipad-landscape.png 
screen-iphone-portrait.png
screen-iphone-portrait-2x.png
screen-iphone-portrait-568h-2x.png

And for Android:

<gap:platform gap:platform="android" gap:density="mdpi" src="res/splash/android/screen-mdpi-portrait.png" />
screen-ldpi-portrait.png
screen-mdpi-portrait.png
screen-hdpi-portrait.png
screen-xhdpi-portrait.png

@LinusU
Copy link
Author

LinusU commented Dec 31, 2013

(Sorry for late reply, didn't get any notifications...)

@kunik Are you sure that the file has the executable bit set?

chmod +x .cordova/hooks/after_prepare/icons_and_splash.js

@LinusU
Copy link
Author

LinusU commented Dec 31, 2013

(Sorry for late reply, didn't get any notifications...)

@SyntheCypher couldn't agree more, this is insane!

Thanks for the clarification on the convert.sh file, I added your comment in it, shout at me if you want it removed.

@LinusU
Copy link
Author

LinusU commented Dec 31, 2013

@unexist Thanks, I updated the typo.

My reasoning for using throw was that the user would report the error and we can add in support for more platforms as that happens.

@LinusU
Copy link
Author

LinusU commented Dec 31, 2013

@numediaweb To put it in the platforms/android/res/drawable* folders is the only thing that actually works, but that is bad since the platform folder is supposed to be generated and not checked in into git (or svn or whatever).

This script enables you to have your icons inside the www folder instead, as the manual says in the top.

@mytharcher
Copy link

The image path placeholder in convert command could be changed to $1, and then the usage could be:

$ sh convert.sh my-icon.png

I think this would be more flexiable so that no hard code in the script.

@LinusU
Copy link
Author

LinusU commented Jan 23, 2014

@mytharcher, fixed

@niiamon
Copy link

niiamon commented Feb 25, 2014

I tried running the script but it blew up on me:

module.js:340
throw err;
^
Error: Cannot find module 'cordova/src/util'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/Users/niiamon/projects/awsmsauce/atade/src/live/lukaduka-pos/lukaduka-pos/.cordova/hooks/after_prepare/icons_and_splash.js:3:20)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

Error: Script "/Users/niiamon/projects/awsmsauce/atade/src/live/lukaduka-pos/lukaduka-pos/.cordova/hooks/after_prepare/icons_and_splash.js" exited with status code 8. Aborting. Output:

module.js:340
throw err;
^
Error: Cannot find module 'cordova/src/util'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/Users/niiamon/projects/awsmsauce/atade/src/live/lukaduka-pos/lukaduka-pos/.cordova/hooks/after_prepare/icons_and_splash.js:3:20)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

at /usr/local/lib/node_modules/cordova/src/hooker.js:141:34
at ChildProcess.exithandler (child_process.js:641:7)
at ChildProcess.EventEmitter.emit (events.js:98:17)
at maybeClose (child_process.js:735:16)
at Socket.<anonymous> (child_process.js:948:11)
at Socket.EventEmitter.emit (events.js:95:17)
at Pipe.close (net.js:466:12)

I suppose it's because I am missing some cordova utils. What do I need to install?

@niiamon
Copy link

niiamon commented Feb 25, 2014

I got this fixed by running:

npm install cordova in the root of my project folder.

However I still have other problems when I run cordova build ios:

throw new Error('Platform and density not supported: ' + platform + ', ' +

I'm at a loss what this means. It appears the script expect the ios icons to have density information in the tags in the config.xml. Not too sure what that means.

@niiamon
Copy link

niiamon commented Feb 25, 2014

I fixed this. I had copied and pasted some directives into the config.xml from some other place and that was messing things up. But now splash screens do not work at all. I don't see the script trying to copy it.

@niiamon
Copy link

niiamon commented Feb 25, 2014

I finally fixed my problem. It appears that the script is looking for a gap:splash tag within config.xml as the following lines from icons_and_splash.js shows:

projectConfig.doc.findall('*').filter(function (node) {
return (node.tag == 'gap:splash');
}).map(function (node) {
copyAsset ('splash', node);
});

However, @LinusU recommended that we have this in the config.xml:

<gap:platform gap:platform="ios" src="res/splash/ios/screen-iphone-portrait.png" />

Obviously the script would fail to find the splash because there's a mismatch between what it expects the tag to be and what the tag actually is.

The simple solution I used was to instead use this tag within the config.xml file:

<gap:splash gap:platform="ios" src="res/splash/ios/screen-ipad-portrait.png" />

Combining that with the properly named files, I was able to get splash screens also working correctly.

@antoineF
Copy link

convert.sh for Mac :

#
# (OS X)
#
# What is this?
#
# It's a shell script that is using sips to create all the icon files from one source icon.
#
# Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Terminal.
#

ICON=${1:-"my-hires-icon.png"}

mkdir android
sips $ICON -Z 36 -o android/icon-36-ldpi.png
sips $ICON -Z 48 -o android/icon-48-mdpi.png
sips $ICON -Z 72 -o android/icon-72-hdpi.png
sips $ICON -Z 96 -o android/icon-96-xhdpi.png

mkdir ios
sips $ICON -Z 29 -o ios/icon-29.png
sips $ICON -Z 40 -o ios/icon-40.png 
sips $ICON -Z 50 -o ios/icon-50.png 
sips $ICON -Z 57 -o ios/icon-57.png
sips $ICON -Z 58 -o ios/icon-29-2x.png
sips $ICON -Z 60 -o ios/icon-60.png
sips $ICON -Z 72 -o ios/icon-72.png
sips $ICON -Z 76 -o ios/icon-76.png  
sips $ICON -Z 80 -o ios/icon-40-2x.png
sips $ICON -Z 100 -o ios/icon-50-2x.png
sips $ICON -Z 114 -o ios/icon-57-2x.png     
sips $ICON -Z 120 -o ios/icon-60-2x.png
sips $ICON -Z 144 -o ios/icon-72-2x.png
sips $ICON -Z 152 -o ios/icon-76-2x.png

@klikin
Copy link

klikin commented Mar 1, 2014

Hi:

Got an error :(

$ cordova run android
Generating config.xml from defaults for platform "android"
Preparing android project

/usr/local/lib/node_modules/cordova/node_modules/q/q.js:126
throw e;
^
Error: Script "/project/.cordova/hooks/after_prepare/icons_and_splash.js" exited with status code 8. Aborting. Output:

/project/.cordova/hooks/after_prepare/icons_and_splash.js:6
var projectConfig = new cordova_util.config_parser(projectXml);
^
TypeError: undefined is not a function
at Object. (/project/.cordova/hooks/after_prepare/icons_and_splash.js:6:21)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3

at /usr/local/lib/node_modules/cordova/src/hooker.js:138:34
at ChildProcess.exithandler (child_process.js:641:7)
at ChildProcess.EventEmitter.emit (events.js:98:17)
at maybeClose (child_process.js:735:16)
at Socket.<anonymous> (child_process.js:948:11)
at Socket.EventEmitter.emit (events.js:95:17)
at Pipe.close (net.js:466:12)

@jernejcic
Copy link

@klikin, did you figure this out? I'm getting the same thing but on Windows. It runs fine on my Mac though.

@slawo
Copy link

slawo commented Mar 20, 2014

config_parser has been removed in this commit: apache/cordova-cli@45e80ac#diff-34a6d62af0cf0b784f8444529f3130ef

replace

var projectConfig = new cordova_util.config_parser(projectXml);

with

var ConfigParser = cordova_util.config_parser
if(undefined === ConfigParser) {
    ConfigParser = require('cordova/src/ConfigParser');
}
var projectConfig = new ConfigParser(projectXml);

@hartman
Copy link

hartman commented Mar 26, 2014

i've made some changes in my version: https://gist.github.com/hartman/9784684

it includes slawo's change, but also supports the older method
has winphone support
warns about missing icons
warns when no icons are not defined in config.xml

@niiamon
Copy link

niiamon commented Apr 2, 2014

@hartman I get some breaking errors although the copy action for icons works well:

Update all icons for project: MyProject

copying from res/icons/android/icon-36-ldpi.png to the platforms/android/res/drawable-ldpi/icon.png

copying from res/icons/android/icon-48-mdpi.png to the platforms/android/res/drawable-mdpi/icon.png

copying from res/icons/android/icon-72-hdpi.png to the platforms/android/res/drawable-hdpi/icon.png

copying from res/icons/android/icon-96-xhdpi.png to the platforms/android/res/drawable-xhdpi/icon.png

copying from res/icons/ios/icon-29.png to the platforms/ios/MyProject/Resources/icons/icon-small.png

copying from res/icons/ios/icon-29-2x.png to the platforms/ios/MyProject/Resources/icons/icon-small@2x.png

copying from res/icons/ios/icon-40.png to the platforms/ios/MyProject/Resources/icons/icon-40.png

copying from res/icons/ios/icon-40-2x.png to the platforms/ios/MyProject/Resources/icons/icon-40@2x.png

copying from res/icons/ios/icon-50.png to the platforms/ios/MyProject/Resources/icons/icon-50.png

copying from res/icons/ios/icon-50-2x.png to the platforms/ios/MyProject/Resources/icons/icon-50@2x.png

copying from res/icons/ios/icon-57.png to the platforms/ios/MyProject/Resources/icons/icon.png

copying from res/icons/ios/icon-57-2x.png to the platforms/ios/MyProject/Resources/icons/icon@2x.png

copying from res/icons/ios/icon-60.png to the platforms/ios/MyProject/Resources/icons/icon-60.png

copying from res/icons/ios/icon-60-2x.png to the platforms/ios/MyProject/Resources/icons/icon-60@2x.png

copying from res/icons/ios/icon-72.png to the platforms/ios/MyProject/Resources/icons/icon-72.png

copying from res/icons/ios/icon-72-2x.png to the platforms/ios/MyProject/Resources/icons/icon-72@2x.png

copying from res/icons/ios/icon-76.png to the platforms/ios/MyProject/Resources/icons/icon-76.png

copying from res/icons/ios/icon-76-2x.png to the platforms/ios/MyProject/Resources/icons/icon-76@2x.png

/path/to/.cordova/hooks/after_prepare/icons_and_splash.js:136
throw err;
^
Error: ENOENT, stat 'res/icons/android/icon-36-ldpi.png'
Hook failed with error code 8: /path/to/.cordova/hooks/after_prepare/icons_and_splash.js

I am trying to figure out why this happens. The files are copied successfully and I can confirm that by looking at the icons in the platform folders. They are what you would expect.

The only way I have gotten it to work properly is to change all the throws to console.log to enable to code to fail silently. Any way to fix this?

@rsuper
Copy link

rsuper commented Apr 23, 2014

@niiamon The script can't find the file, so it throws that error.
To make it work, I added these 2 lines on line 132 and 133:

srcPath = projectRoot + '/www/' + srcPath;
dstPath = projectRoot + '/' + dstPath;

Just above - console.log ('copying from '+srcPath+' to the '+dstPath); - where it outputs which file is being copied.
Note: I used the version of @hartman

@Takeno
Copy link

Takeno commented May 1, 2014

@hartman @rsuper @niiamon
The best way to fix relative path issue in the script is:

  1. Include path module after line 10 var path = require('path'); (after fs declaration)
  2. Fix srcPath in line 98 var srcPath = path.join(projectRoot, 'www', node.attrib.src);
  3. Fix dstPath in line 106 var dstPath = path.join(projectRoot, 'platforms', platform, assetDir, fileName);

@AncAinu
Copy link

AncAinu commented May 6, 2014

I forked this gist and fixed issues I found: https://gist.github.com/AncAinu/40b7d85d3c6ed77150aa

@manuganji
Copy link

For ubuntu, instead of mkdir android you can use mkdir -p android to suppress the annoying message when the directory is already present.

@shedd
Copy link

shedd commented Jun 8, 2014

I ran into some issues with Cordova 3.5.0.

Cordova was refactored in this commit: apache/cordova-cli@b51e1c1

Therefore, some changes are required to get this to run under the latest version.

First, in addition to having cordova installed at the root of your project, also install:

npm install cordova-lib

Then, change:

var cordova_util = require('cordova/src/util');

to

var cordova_util = require('cordova-lib/src/cordova/util');

Also, make this change - https://gist.github.com/LinusU/7515016#comment-1195042 - for ConfigParser.

Then change:

ConfigParser = require('cordova/src/ConfigParser');

to

ConfigParser = require('cordova-lib/src/cordova/ConfigParser');

@shedd
Copy link

shedd commented Jun 8, 2014

I've forked the gist and included the updates from @hartman and @Takeno plus the revisions needed for Cordova 3.5.0.

Updated version here: https://gist.github.com/shedd/2bcbecec53ee8cddebfe

@shedd
Copy link

shedd commented Jun 8, 2014

If anyone is looking for a conversion script that handles splash screens, I found this option: https://github.com/tlvince/phonegap-icon-splash-generator

I ended up taking bits and pieces of the two scripts and hooking them both into my build process.

@MGalv
Copy link

MGalv commented Sep 2, 2014

For cordoba-lib version ~> 0.21.4, you should change this line:

CordovaConfigParser = require('cordova-lib/src/cordova/configparser');

for this one:

CordovaConfigParser = require('cordova-lib').configparser;

@3dcinetv
Copy link

It´s been 2 days now, please help me solve this error, please:
On my cmd I type:

D:\VB4>phonegap build android

Then it returns:
[phonegap] executing 'cordova build android'...
D:\VB4\res\icons\ is a directory (not copied)

Running command: "C:\Program Files\nodejs\node.exe" D:\VB4\hooks\after_prepare\i
cons_and_splash.js D:\VB4

module.js:338
throw err;
^

Error: Cannot find module 'cordova/src/util'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:286:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (D:\VB4\hooks\after_prepare\icons_and_splash.js:3:20)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)

Error: Hook failed with error code 1: D:\VB4\hooks\after_prepare\icons_and_splas
h.js

@ekorslin
Copy link

Hi everyone,
I'm getting the following after attempting to run cordova emulate ios with my cordova app. Any suggestions for a fix?

/Users/ekorslin/Desktop/cordovaReactProject/hooks/after_prepare/icons_and_splash.js:127
        throw new Error('Cannot write file');
        ^

Error: Cannot write file
    at WriteStream.<anonymous> (/Users/ekorslin/Desktop/cordovaReactProject/hooks/after_prepare/icons_and_splash.js:127:15)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment