diff --git a/lib/prepare.js b/lib/prepare.js index bf305ef14..c7573806a 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -531,15 +531,43 @@ function updateIcons (cordovaProject, locations) { return Promise.resolve(); } - const platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj); - const iconsDir = path.join(platformProjDir, 'Assets.xcassets', 'AppIcon.appiconset'); - return checkOrAssumeXcodeVersion() .then((xcodeversion) => { + const platformProjDir = path.relative(cordovaProject.root, locations.xcodeCordovaProj); + + // We can only support icon composer folder icons with Xcode 26 + const isAtLeastXcode26 = versions.compareVersions(xcodeversion, '26.0.0') >= 0; + + const iconFolders = icons.filter((icon) => icon.src.endsWith('.icon')); + iconFolders.forEach((icon) => { + if (!isAtLeastXcode26) { + events.emit('warning', `Xcode ${xcodeversion} cannot support icon: ${icon.src}. Skipping...`); + } else if (icon.height || icon.width) { + events.emit('warning', `Cannot specify height or width attributes with Icon Composer icon ${icon.src}. Skipping...`); + } else if (icon.target) { + events.emit('warning', `Cannot specify target attribute with Icon Composer icon ${icon.src}. Skipping...`); + } else { + const project = projectFile.parse(locations); + const target = path.join(platformProjDir, 'AppIcon.icon'); + + const resourceMap = { [target]: icon.src }; + events.emit('verbose', `Copying icon bundle from ${icon.src} to ${target}`); + FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp); + + const appGroup = project.xcode.findPBXGroupKey({ path: 'App' }); + project.xcode.addResourceFile('AppIcon.icon', { lastKnownFileType: 'folder.iconcomposer.icon' }, appGroup); + project.write(); + } + + // Remove it so it won't get copied by mapIconResources + icons.splice(icons.indexOf(icon), 1); + }); + + const iconsDir = path.join(platformProjDir, 'Assets.xcassets', 'AppIcon.appiconset'); + const resourceMap = mapIconResources(icons, iconsDir, xcodeversion); events.emit('verbose', `Updating icons at ${iconsDir}`); - FileUpdater.updatePaths( - resourceMap, { rootDir: cordovaProject.root }, logFileOp); + FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp); // Now we need to update the AppIcon.appiconset/Contents.json file const contentsJSON = generateAppIconContentsJson(resourceMap);