Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parameter --asset-name to specify custom iOS xcasset #138

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Icon management for Mobile Apps. Create icons, generate all required sizes, labe
* [Generating Icons](#generating-icons)
* [Labelling Icons](#labelling-icons)
* [Adaptive Icons](#adaptive-icons)
* [Specific Icon Asset](#specific-icon-asset)
* [Developer Guide](#developer-guide)
* [Initial Setup](#initial-setup)
* [Running Tests](#running-tests)
Expand Down Expand Up @@ -180,6 +181,14 @@ To test how adaptive icons will look when animated, swiped, etc, the [Adaptive I

Note that Adaptive Icons of *all* supported sizes are generated. However, we also generate the `res/mipmap-anydpi-v26/` adaptive icon. This is a large size icon which Android from v26 onwards will automatically rescale as needed to all other sizes. This technically makes the density specific icons redundant. The reason we generate both is to ensure that after `generate` is run, *all* icons in the project will be consistent.

### Specific Icon Asset

Enable to generate icons for an specific xcasset in case your iOS app supports more than one scheme with different icons

```
--asset-name CustomAppIcon
```

## Developer Guide

The only dependencies are Node 8 (or above) and Yarn.
Expand Down
3 changes: 3 additions & 0 deletions bin/app-icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ program
.option('--background-icon [optional]', "The background icon path. Defaults to 'icon.background.png'")
.option('--foreground-icon [optional]', "The foreground icon path. Defaults to 'icon.foreground.png'")
.option('--adaptive-icons [optional]', "Additionally, generate Android Adaptive Icon templates. Defaults to 'false'")
.option('--asset-name [optional]', "Set iOS iconset other than default 'AppIcon.appiconset'")
.action(async (parameters) => {
const {
icon,
Expand All @@ -54,6 +55,7 @@ program
search,
platforms,
adaptiveIcons,
assetName,
} = parameters;

await imageMagickCheck();
Expand All @@ -75,6 +77,7 @@ program
searchRoot: search,
platforms,
adaptiveIcons,
assetName,
});
} catch (err) {
console.error(chalk.red(`An error occurred generating the icons: ${err.message}`));
Expand Down
13 changes: 12 additions & 1 deletion src/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = async function generate(parameters) {
searchRoot,
platforms,
adaptiveIcons,
assetName
} = validateParameters(parameters || {});

// Set up the results object.
Expand All @@ -24,7 +25,12 @@ module.exports = async function generate(parameters) {
adaptiveIconManifests: [],
};

const iconSets = await findIconsetFolders(searchRoot);
const iconSets = await findIconsetFolders(searchRoot, assetName);

if(iconSets.length === 0){
console.error(chalk.red(`No iconset found in xcode project`));
}

await Promise.all(iconSets.map(async (iconset) => {
if (!platforms.includes('ios')) return null;
console.log(`Found iOS iconset: ${iconset}...`);
Expand Down Expand Up @@ -59,5 +65,10 @@ module.exports = async function generate(parameters) {

return null;
}));

if(manifests.length === 0){
console.error(chalk.red(`No manifest found in android project`));
}

return results;
};
15 changes: 15 additions & 0 deletions src/generate.specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ describe('generate', () => {
expect(results.manifests.length).to.equal(4);
});

it('should be able to generate icons for Custom xcasset set', async () => {
const parameters = {
sourceIcon: './test/icon.png',
searchPath: './',
assetName: 'CustomAppIcon'
};

// Delete all of the files we're expecting to create, then generate them.
const results = await generate(parameters);
// TODO: Check we found the manifests etc etc
expect(results).not.to.equal(null);
expect(results.iconsets.length).to.equal(1);
expect(results.manifests.length).to.equal(4);
});

it('should be able to generate test app icons with adaptive icons included', async () => {
const parameters = {
sourceIcon: './test/icon.png',
Expand Down
7 changes: 5 additions & 2 deletions src/ios/find-iconset-folders.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
const find = require('../utils/find');

// Given a search root, finds all iOS iconsets.
module.exports = async function findIconsetFolders(searchRoot) {
module.exports = async function findIconsetFolders(searchRoot, iconSet) {
return find(searchRoot, (file, stat) => {
// exclude node modules from the search.
if (file.match(/node_modules/)) return false;

// only grab the iconset folders.
return file.match(/AppIcon.appiconset/) && stat.isDirectory();
const iconsetPattern = '\/' + (iconSet || 'AppIcon') + '.appiconset$';
const iconsetRegex = new RegExp(iconsetPattern);

return file.match(iconsetRegex) && stat.isDirectory();
});
};
2 changes: 2 additions & 0 deletions src/validate-parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = function validateParameters(parameters) {
const adaptiveIcons = !!parameters.adaptiveIcons;
const backgroundIcon = parameters.backgroundIcon || 'icon.background.png';
const foregroundIcon = parameters.foregroundIcon || 'icon.foreground.png';
const assetName = parameters.assetName || '';

return {
sourceIcon,
Expand All @@ -28,5 +29,6 @@ module.exports = function validateParameters(parameters) {
searchRoot,
platforms,
adaptiveIcons,
assetName,
};
};
6 changes: 6 additions & 0 deletions test/NativeApp/ios/native_app/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
{
"images" : [
{
"filename" : "iphone-20x20-2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "iphone-20x20-3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "iphone-29x29-1x.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "iphone-29x29-2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "iphone-29x29-3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "iphone-40x40-2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "iphone-40x40-3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "iphone-57x57-1x.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "57x57"
},
{
"filename" : "iphone-57x57-2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "57x57"
},
{
"filename" : "iphone-60x60-2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "iphone-60x60-3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "ipad-20x20-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "ipad-20x20-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "ipad-29x29-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "ipad-29x29-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "ipad-40x40-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "ipad-40x40-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "ipad-50x50-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "50x50"
},
{
"filename" : "ipad-50x50-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "50x50"
},
{
"filename" : "ipad-72x72-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "72x72"
},
{
"filename" : "ipad-72x72-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "72x72"
},
{
"filename" : "ipad-76x76-1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "ipad-76x76-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "ipad-83.5x83.5-2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "ios-marketing-1024x1024-1x.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading