### Install dependencies
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/CONTRIBUTING.md
Initializes the project by installing required packages.
```bash
yarn install
```
--------------------------------
### Test changes in example app
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/CONTRIBUTING.md
Navigates to the example directory and prepares the native projects for testing.
```bash
cd example
yarn expo prebuild --clean
yarn expo run:ios # or yarn expo run:android
```
--------------------------------
### Install and Prebuild
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Install the library and prebuild your Expo project to apply native changes.
```bash
npx expo install expo-alternate-app-icons
npx expo prebuild --clean
```
--------------------------------
### Common Usage Patterns
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Provides practical examples of how to use the core API functions in common scenarios, such as checking support, setting, getting, and resetting app icons.
```APIDOC
## Common Usage Patterns
Provides practical examples of how to use the core API functions in common scenarios, such as checking support, setting, getting, and resetting app icons.
### Check Support & Set Icon
```typescript
if (supportsAlternateIcons) {
try {
await setAlternateAppIcon('IconA');
} catch (error) {
console.error('Failed to set icon:', error);
}
}
```
### Get Current Icon
```typescript
const current = getAppIconName();
console.log(current === null ? 'Default icon' : `Current: ${current}`);
```
### Reset to Default
```typescript
await resetAppIcon();
```
### Toggle Between Icons
```typescript
const current = getAppIconName();
const newIcon = current === 'IconA' ? 'IconB' : 'IconA';
await setAlternateAppIcon(newIcon);
```
```
--------------------------------
### Android Configuration Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/README.md
Configuration for Android, defining an adaptive icon with foreground and background layers within app.json.
```json
{
"expo": {
"plugins": [
["expo-alternate-app-icons", {
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/icons/adaptive-foreground.png",
"backgroundImage": "./assets/icons/adaptive-background.png",
"backgroundColor": "#ffffff"
}
}
}]
]
}
}
```
--------------------------------
### iOS Configuration Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/README.md
Configuration for iOS, specifying a single image or light/dark/tinted variants for alternate app icons within app.json.
```json
{
"expo": {
"plugins": [
["expo-alternate-app-icons", {
"ios": {
"icons": [
{
"name": "new-icon-name",
"image": "./assets/icons/new-icon.png",
"idiom": "universal",
"variants": {
"dark": "./assets/icons/new-icon-dark.png",
"light": "./assets/icons/new-icon-light.png",
"tinted": "./assets/icons/new-icon-tinted.png"
}
}
]
}
}]
]
}
}
```
--------------------------------
### Install Library
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/README.md
Use Expo CLI to add the library to your project dependencies.
```sh
npx expo install expo-alternate-app-icons
```
--------------------------------
### Example Android Adaptive Icon Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/types.md
An example of a complete Android adaptive icon configuration, including paths for foreground, background, and monochrome images, along with a background color.
```json5
{
"foregroundImage": "./assets/icon-foreground.png",
"backgroundColor": "#001413",
"backgroundImage": "./assets/icon-background.png",
"monochromeImage": "./assets/icon-monochrome.png"
}
```
--------------------------------
### Example Plugin Composition in app.json
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Demonstrates how to include the expo-alternate-app-icons plugin alongside other community and Expo plugins within the 'plugins' array in app.json.
```json5
{
"plugins": [
"@react-native-firebase/app",
["expo-alternate-app-icons", [...]],
"expo-build-properties",
["expo-camera", ...]
]
}
```
--------------------------------
### iOSVariantsIcon Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/types.md
An example of the `iOSVariantsIcon` object, specifying image paths for light, dark, and tinted appearances.
```json5
{
"light": "./assets/icon-light.png",
"dark": "./assets/icon-dark.png",
"tinted": "./assets/icon-tinted.png"
}
```
--------------------------------
### AlternateIcon Configuration Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/types.md
An example of the JSON configuration for a single alternate app icon, including paths for iOS variants and Android adaptive icon properties.
```json5
{
"name": "IconA",
"ios": {
"light": "./assets/icon-a-light.png",
"dark": "./assets/icon-a-dark.png",
"tinted": "./assets/icon-a-tinted.png"
},
"android": {
"foregroundImage": "./assets/icon-a-foreground.png",
"backgroundColor": "#001413",
"backgroundImage": "./assets/icon-a-background.png",
"monochromeImage": "./assets/icon-a-monochrome.png"
}
}
```
--------------------------------
### Generated AlternateAppIcons Type Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/types.md
Example of how the `AlternateAppIcons` type is generated at build time with literal union values based on plugin configuration.
```typescript
export type AlternateAppIcons = 'IconA' | 'IconB' | 'IconC';
```
--------------------------------
### Android Manifest Activity Alias Example
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
An example of an activity alias added to AndroidManifest.xml for an alternate app icon, enabling it for the launcher.
```xml
```
--------------------------------
### Complete Configuration Example for app.json
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
This JSON5 snippet shows a full configuration for the expo-alternate-app-icons plugin within the app.json file. It defines multiple alternate icons for both iOS and Android platforms, specifying image paths and color configurations.
```json5
{
"expo": {
"name": "MyApp",
"slug": "my-app",
"plugins": [
[
"expo-alternate-app-icons",
[
{
"name": "IconA",
"ios": {
"light": "./assets/icons/icon-a-light.png",
"dark": "./assets/icons/icon-a-dark.png",
"tinted": "./assets/icons/icon-a-tinted.png"
},
"android": {
"foregroundImage": "./assets/icons/icon-a-foreground.png",
"backgroundColor": "#001413"
}
},
{
"name": "IconB",
"ios": "./assets/icons/icon-b.png",
"android": {
"foregroundImage": "./assets/icons/icon-b-foreground.png",
"backgroundColor": "#FF6B6B",
"backgroundImage": "./assets/icons/icon-b-background.png"
}
},
{
"name": "IconC",
"ios": {
"light": "./assets/icons/icon-c-light.png",
"dark": "./assets/icons/icon-c-dark.png",
"tinted": "./assets/icons/icon-c-tinted.png"
},
"android": {
"foregroundImage": "./assets/icons/icon-c-foreground.png",
"backgroundColor": "#4ECDC4",
"monochromeImage": "./assets/icons/icon-c-monochrome.png"
}
}
]
]
]
}
}
```
--------------------------------
### Platform-Specific Web Handling for App Icons
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/usage-examples.md
This example demonstrates how to check if alternate app icon switching is available on the current platform and provides a function to set the app icon only if supported, logging messages for unsupported platforms or errors.
```typescript
import {
setAlternateAppIcon,
supportsAlternateIcons
} from 'expo-alternate-app-icons';
import { Platform } from 'react-native';
export function isIconSwitchingAvailable(): boolean {
// Only available on mobile platforms
return (
supportsAlternateIcons &&
Platform.OS !== 'web'
);
}
export async function setAppIconIfSupported(
iconName: string
): Promise {
if (!isIconSwitchingAvailable()) {
console.info('Icon switching not available on this platform');
return false;
}
try {
await setAlternateAppIcon(iconName as any);
return true;
} catch (error) {
console.error('Failed to set icon:', error);
return false;
}
}
```
--------------------------------
### Project Structure
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Illustrates the directory layout of the expo-alternate-app-icons project, detailing the placement of source code, configuration plugins, native implementations, and example applications.
```tree
expo-alternate-app-icons/
├── src/ # JavaScript/TypeScript API
│ ├── index.ts # Main entry point, exported functions
│ ├── AlternateAppIconsType.ts # Type definition (auto-generated)
│ ├── ExpoAlternateAppIconsModule.ts # Native module wrapper
│ └── ExpoAlternateAppIconsModule.web.ts # Web platform stub
│
├── plugin/ # Expo Config Plugin
│ ├── src/
│ │ ├── index.ts # Plugin entry point
│ │ ├── types.ts # Type definitions
│ │ ├── utils.ts # Helper functions
│ │ ├── ios/ # iOS-specific plugin code
│ │ │ ├── withAlternateAppIconsGenerator.ts
│ │ │ ├── withXcodeProjectUpdate.ts
│ │ │ ├── generateUniversalIcon.ts
│ │ │ └── writeContentsJson.ts
│ │ └── android/ # Android-specific plugin code
│ │ ├── withAdaptiveIconsGenerator.ts
│ │ ├── withAndroidManifestUpdate.ts
│ │ └── generateAdaptiveIcon.ts
│ └── tsconfig.json
│
├── ios/ # Native iOS implementation
│ └── ExpoAlternateAppIconsModule.swift
│
├── android/ # Native Android implementation
│ └── src/main/java/expo/modules/alternateappicons/
│ └── ExpoAlternateAppIconsModule.kt
│
├── example/ # Example Expo app
│ ├── app.json # Plugin configuration example
│ └── App.tsx # Usage example
│
├── package.json # Package metadata
├── app.plugin.js # Plugin entry point
├── expo-module.config.json # Native module definitions
└── README.md # Documentation
```
--------------------------------
### iOS Contents.json Output Format (Single Image)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Example JSON structure for a single-image iOS app icon set's Contents.json file.
```json
{
"images": [
{
"filename": "icon.png",
"idiom": "universal",
"platform": "ios",
"size": "1024x1024"
}
],
"info": {
"author": "expo",
"version": 1
}
}
```
--------------------------------
### Icon Name Configuration Data Flow
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Details the process of configuring icon names, starting from the app.json file, through input validation and transformation, to the final extraction and generation of type definition files.
```tree
app.json
↓
└─ Plugin Configuration (AlternateIcon[])
↓
└─ Input Validation & Transformation
├─ isPathArray() check
├─ toAlternateIcon() conversion (if paths)
└─ toPascalCaseIconName() normalization
↓
└─ Icon Names Extracted
↓
└─ generateTypeIconsFile()
└─ Generates: src/AlternateAppIconsType.ts
```
--------------------------------
### iOS Contents.json Output Format (Variant-Based)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Example JSON structure for a variant-based iOS app icon set's Contents.json file, including support for dark mode appearances.
```json
{
"images": [
{
"filename": "icon-light.png",
"idiom": "universal",
"platform": "ios",
"size": "1024x1024"
},
{
"filename": "icon-dark.png",
"idiom": "universal",
"platform": "ios",
"size": "1024x1024",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"filename": "icon-tinted.png",
"idiom": "universal",
"platform": "ios",
"size": "1024x1024",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
}
],
"info": {
"author": "expo",
"version": 1
}
}
```
--------------------------------
### Persist App Icon Preference with AsyncStorage
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/usage-examples.md
This example demonstrates how to save and load the user's preferred app icon using AsyncStorage. It includes functions to load saved preferences on app initialization and to save the current icon choice.
```typescript
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
setAlternateAppIcon,
getAppIconName,
resetAppIcon,
type AlternateAppIcons
} from 'expo-alternate-app-icons';
const ICON_PREFERENCE_KEY = 'app_icon_preference';
export async function loadSavedIcon(): Promise {
try {
const savedIcon = await AsyncStorage.getItem(ICON_PREFERENCE_KEY);
if (savedIcon && savedIcon !== 'default') {
// Only change if different from current
const current = getAppIconName();
if (current !== savedIcon) {
await setAlternateAppIcon(savedIcon as AlternateAppIcons);
}
}
} catch (error) {
console.error('Failed to load saved icon:', error);
}
}
export async function saveAndApplyIcon(
iconName: AlternateAppIcons | null
): Promise {
try {
// Apply the icon
if (iconName === null) {
await resetAppIcon();
} else {
await setAlternateAppIcon(iconName);
}
// Save preference
const preference = iconName || 'default';
await AsyncStorage.setItem(ICON_PREFERENCE_KEY, preference);
} catch (error) {
console.error('Failed to save icon preference:', error);
throw error;
}
}
// On app initialization
export async function initializeAppIcon(): Promise {
await loadSavedIcon();
}
```
--------------------------------
### Core API Functions
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
This section details the core functions available in the expo-alternate-app-icons library for managing app icons. It includes functions to check for support, set, get, and reset app icons.
```APIDOC
## Core API Functions
This section details the core functions available in the `expo-alternate-app-icons` library for managing app icons. It includes functions to check for support, set, get, and reset app icons.
### `supportsAlternateIcons`
- **Description**: A constant boolean value indicating whether the current platform supports alternate app icons.
- **Returns**: `boolean`
### `setAlternateAppIcon(name)`
- **Description**: Asynchronously changes the app icon to the specified alternate icon. Use `null` to reset to the default icon.
- **Parameters**:
- **name** (`AlternateAppIcons | null`) - The name of the alternate icon to set, or `null` to reset.
- **Returns**: `Promise` - A promise that resolves with the name of the icon that was set, or `null` if reset.
### `getAppIconName()`
- **Description**: Synchronously retrieves the name of the currently active app icon.
- **Returns**: `AlternateAppIcons | null` - The name of the current icon, or `null` if the default icon is active.
### `resetAppIcon()`
- **Description**: Asynchronously resets the app icon to the default icon defined in the project.
- **Returns**: `Promise`
```
--------------------------------
### Run Prebuild Process
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Execute this command to apply the plugin's configuration to your native projects. This command cleans the existing native projects before rebuilding them with the new configurations.
```bash
npx expo prebuild --clean
```
--------------------------------
### Build the project
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/CONTRIBUTING.md
Compiles the source code for the project.
```bash
yarn build
```
--------------------------------
### Configuration Transformation Pipeline
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Details the step-by-step process of transforming app icon configurations from `app.json` to native project readiness.
```text
Input (app.json)
↓
string[] | AlternateIcon[]
↓
isPathArray() → type guard
↓
├─ true: toAlternateIcon() → AlternateIcon[]
└─ false: AlternateIcon[] (already correct type)
↓
toPascalCaseIconName() → normalize all names
↓
Extract icon names
↓
generateTypeIconsFile() → AlternateAppIcons type union
↓
Platform-specific generation
├─ iOS: process via withAlternateAppIconsGenerator
└─ Android: process via withAdaptiveIconsGenerator
↓
Manifest updates
├─ iOS: withXcodeProjectUpdate
└─ Android: withAndroidManifestUpdate
↓
Output (Native projects ready for build)
```
--------------------------------
### Get Current Icon Name
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/README.md
Retrieve the name of the currently active app icon.
```ts
function getAppIconName(): string | null;
```
--------------------------------
### Single Icon Configuration (Simple Path)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Shows how to configure a single alternate icon using just a file path string in the plugin configuration array.
```json5
[
"expo-alternate-app-icons",
[
"./assets/icon-a.png",
"./assets/icon-b.png"
]
]
```
--------------------------------
### Build Development Plugin
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/README.md
Commands to build the plugin and apply changes via prebuild.
```shell
yarn run build plugin # Start build on save
cd example && yarn expo prebuild # Execute the config plugin
```
--------------------------------
### Get Simple Component Name
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/native-modules.md
Extracts the simple class name from a fully qualified Android component name. This is a helper function for parsing component names.
```kotlin
private fun getSimpleName(component: ComponentName): String =
component.className.split('.').last()
```
--------------------------------
### Check Generated Files After Prebuild
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Verify the existence and content of generated files, including type definitions, iOS icon sets, Android resources, and the Android manifest.
```bash
# Check generated type file
cat src/AlternateAppIconsType.ts
# Check iOS resources
find ios -name "*.appiconset" -type d
# Check Android resources
find android/app/src/main/res -name "ic_launcher_*"
# Check manifest
cat android/app/src/main/AndroidManifest.xml
```
--------------------------------
### Get Current App Icon Name
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Retrieve the name of the currently active app icon synchronously. Logs whether the default or a specific icon is active.
```typescript
const current = getAppIconName();
console.log(current === null ? 'Default icon' : `Current: ${current}`);
```
--------------------------------
### iOS File Paths After Build
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Illustrates the directory structure for alternate app icons within the iOS build output.
```text
ios//Images.xcassets/.appiconset/
├── .png
└── Contents.json
```
--------------------------------
### Get Current App Icon Name
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/api-reference.md
Retrieves the name of the currently active app icon. Returns `null` if the default icon is in use. This function is not supported on Web.
```typescript
export function getAppIconName(): AlternateAppIcons | null
```
```javascript
import { getAppIconName } from 'expo-alternate-app-icons';
const currentIcon = getAppIconName();
if (currentIcon) {
console.log(`Current icon: ${currentIcon}`);
} else {
console.log('Using default icon');
}
```
--------------------------------
### Core API Functions
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/README.md
These are the primary functions exported by the library for runtime use. They allow checking support, setting icons, getting the current icon name, and resetting to the default.
```typescript
import {
supportsAlternateIcons,
setAlternateAppIcon,
getAppIconName,
resetAppIcon,
} from 'expo-alternate-app-icons';
// Example usage:
async function checkAndSetIcon() {
const supported = await supportsAlternateIcons();
if (supported) {
await setAlternateAppIcon('new-icon-name');
const currentIcon = await getAppIconName();
console.log('Current icon:', currentIcon);
} else {
console.log('Alternate icons are not supported on this device.');
}
}
// To reset to the default icon:
// await resetAppIcon();
```
--------------------------------
### Full Icon Configuration Object
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Illustrates using a full AlternateIcon object for detailed configuration of an alternate app icon.
```json5
[
"expo-alternate-app-icons",
[
{
"name": "IconA",
"ios": "./assets/icon-a.png",
"android": {
"foregroundImage": "./assets/icon-a-foreground.png",
"backgroundColor": "#001413"
}
}
]
]
```
--------------------------------
### Configuration (app.json)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Illustrates how to configure alternate app icons within the `app.json` file using the `expo-alternate-app-icons` plugin.
```APIDOC
## Configuration (app.json)
This section illustrates how to configure alternate app icons within the `app.json` file using the `expo-alternate-app-icons` plugin.
### Plugin Configuration
```json5
{
"plugins": [
[
"expo-alternate-app-icons",
[
{
"name": "IconA",
"ios": "./assets/icon-a.png",
"android": {
"foregroundImage": "./assets/icon-a-foreground.png",
"backgroundColor": "#001413"
}
}
]
]
]
}
```
### iOS Configuration
#### Single Icon
```json5
{
"ios": "./assets/icon.png"
}
```
#### With Variants (light/dark/tinted)
```json5
{
"ios": {
"light": "./assets/icon-light.png",
"dark": "./assets/icon-dark.png",
"tinted": "./assets/icon-tinted.png"
}
}
```
**Icon Requirements**: PNG, 1024x1024 px, no transparency
### Android Configuration
#### Required Fields for Adaptive Icon
```json5
{
"android": {
"foregroundImage": "./assets/icon-foreground.png",
"backgroundColor": "#001413"
}
}
```
#### Optional Fields for Adaptive Icon
```json5
{
"android": {
"foregroundImage": "./assets/icon-foreground.png",
"backgroundColor": "#001413",
"backgroundImage": "./assets/icon-background.png",
"monochromeImage": "./assets/icon-monochrome.png"
}
}
```
**Icon Requirements**: PNG, 1024x1024 px, transparent background for foreground.
**Adaptive Icon**: Requires `backgroundColor` or `backgroundImage` for adaptive icon format.
```
--------------------------------
### Enable Verbose Output for Plugin Execution
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Run the Expo prebuild command with the --verbose flag to see detailed plugin execution logs.
```bash
npx expo prebuild --clean --verbose
```
--------------------------------
### Get Current App Icon Name
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/native-modules.md
Retrieves the name of the currently active alternate app icon by examining the active activity component. Returns null if the default icon is active or if the activity provider is unavailable.
```kotlin
private fun getAppIconName(): String? {
val currentActivityComponent = appContext.activityProvider?.currentActivity?.componentName ?: return null
return try {
retrieveIconNameFromComponent(currentActivityComponent)
} catch (error: PackageManager.NameNotFoundException) {
null
}
}
```
--------------------------------
### Basic Plugin Configuration in app.json
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Demonstrates the basic structure for configuring the expo-alternate-app-icons plugin in your app.json file, including a single alternate icon.
```json5
{
"expo": {
"plugins": [
[
"expo-alternate-app-icons",
[
{
"name": "IconA",
"ios": "./assets/icon-a.png",
"android": {
"foregroundImage": "./assets/icon-a-foreground.png",
"backgroundColor": "#001413"
}
}
]
]
]
}
}
```
--------------------------------
### Convert Icon Name to PascalCase
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-functions.md
Converts an icon name within an AlternateIcon object to PascalCase if it starts with a lowercase letter, logging a warning. Returns a new object with the converted name or the original if already PascalCase.
```typescript
export function toPascalCaseIconName(icon: AlternateIcon): AlternateIcon
```
```typescript
const icon = {
name: 'my-icon',
ios: './assets/icon.png',
android: { foregroundImage: './assets/icon.png' }
};
const result = toPascalCaseIconName(icon);
// Logs warning: "Alternate app icon name 'my-icon' should be in PascalCase (e.g. 'IconName')."
// Results in:
// {
// name: 'MyIcon',
// ios: './assets/icon.png',
// android: { foregroundImage: './assets/icon.png' }
// }
```
--------------------------------
### Runtime Icon Switching Flow
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Illustrates the flow for switching app icons at runtime, from user code to native implementations on iOS and Android.
```text
User Code
↓
└─ setAlternateAppIcon(name)
↓
├─ JavaScript/TypeScript
│ └─ ExpoAlternateAppIconsModule.setAlternateAppIcon(name)
│ └─ Native Bridge (Expo Modules)
│
└─ Native Implementation
├─ iOS:
│ └─ UIApplication.shared.setAlternateIconName(name)
│ └─ System Icon Database
│
└─ Android:
├─ Get current Activity component
├─ Create new Activity Alias component name
├─ PackageManager.setComponentEnabledSetting()
│ ├─ Enable new alias
│ └─ Disable current activity
└─ Launcher picks up new component
```
--------------------------------
### Android Required Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Configure the required foreground image and background color for Android adaptive icons in app.json.
```json5
{
"android": {
"foregroundImage": "./assets/icon-foreground.png",
"backgroundColor": "#001413"
}
}
```
--------------------------------
### Configure Alternate Icons in app.json
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Define alternate app icons within the app.json configuration file using the plugins array.
```json5
{
"plugins": [
[
"expo-alternate-app-icons",
[
{
"name": "IconA",
"ios": "./assets/icon-a.png",
"android": {
"foregroundImage": "./assets/icon-a-foreground.png",
"backgroundColor": "#001413"
}
}
]
]
]
}
```
--------------------------------
### Run linting
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/CONTRIBUTING.md
Executes the linting process to ensure code quality before submission.
```bash
yarn lint
```
--------------------------------
### iOS Icon File Structure
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Illustrates the directory structure for alternate app icons within an iOS project's Assets.xcassets folder.
```text
ios/
/
Images.xcassets/
IconA.appiconset/
icon.png
Contents.json
IconB.appiconset/
icon-light.png
icon-dark.png
icon-tinted.png
Contents.json
```
--------------------------------
### Android File Paths After Build
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Shows the file paths for alternate app icons in the Android build output, including mipmap resources and AndroidManifest.xml modifications.
```text
android/app/src/main/res/
├── mipmap-mdpi/ic_launcher_.png
├── mipmap-hdpi/ic_launcher_.png
├── mipmap-xhdpi/ic_launcher_.png
├── mipmap-xxhdpi/ic_launcher_.png
├── mipmap-xxxhdpi/ic_launcher_.png
└── mipmap-anydpi-v26/ic_launcher_.xml
AndroidManifest.xml
└──
```
--------------------------------
### Error Handling for Setting App Icon
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Demonstrates how to catch and log errors that may occur when attempting to set an alternate app icon. Includes platform-specific error types.
```typescript
try {
await setAlternateAppIcon('IconA');
} catch (error) {
// On iOS: UIApplication error (invalid name, icon not found)
// On Android: PackageManager error (system error)
// On Web: UnavailabilityError
console.error('Failed to change icon:', error.message);
}
```
--------------------------------
### Configuration Plugin Lifecycle
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Outlines the lifecycle of an Expo configuration plugin, from parsing app.json to applying modifiers and passing the final configuration to native build tools.
```plaintext
1. app.json parsed
2. Expo loads plugins array
3. Plugin function called: withAlternateAppIcons(config, props)
4. Modifiers applied in order
5. Each modifier wraps the previous result
6. Final config passed to native build tools
7. Prebuild creates native projects
```
--------------------------------
### Plugin Entry Point
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
This JavaScript snippet shows the entry point for the Expo plugin, which should be required in your app.plugin.js file.
```javascript
// app.plugin.js
module.exports = require('./plugin/build');
```
--------------------------------
### Build-Time Dependencies (Plugin)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Maps out the build-time dependencies related to the Expo Config Plugin, illustrating the pipeline for iOS and Android, including specific functions and their roles in modifying project configurations.
```tree
app.plugin.js (entry point)
└── plugin/src/index.ts (withAlternateAppIcons)
├── → plugin/src/types.ts
├── → plugin/src/utils.ts
│ ├── toAlternateIcon()
│ ├── toPascalCaseIconName()
│ ├── generateTypeIconsFile()
│ ├── isPathArray()
│ ├── isIosVariantsIcon()
│ ├── toPascalCase()
│ └── toSnakeCase()
│
├── iOS Pipeline
│ ├── withAlternateAppIconsGenerator()
│ │ └── → plugin/src/ios/generateUniversalIcon.ts
│ │ ├── generateUniversalIcon()
│ │ └── generateUniversalVariantsIcon()
│ │ └── → plugin/src/ios/writeContentsJson.ts
│ └── withXcodeProjectUpdate()
│ └── Updates ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES
│
└── Android Pipeline
├── withAdaptiveIconsGenerator()
│ └── → plugin/src/android/generateAdaptiveIcon.ts
│ ├── generateAdaptiveIcon()
│ ├── generateMultiLayerImageAsync()
│ ├── generateMonochromeImageAsync()
│ └── createAdaptiveIconXmlString()
└── withAndroidManifestUpdate()
└── Adds activity aliases to AndroidManifest.xml
```
--------------------------------
### Import All Exports
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/api-reference.md
Demonstrates how to import all exported symbols from the main 'expo-alternate-app-icons' package.
```typescript
import {
supportsAlternateIcons,
setAlternateAppIcon,
getAppIconName,
resetAppIcon,
type AlternateAppIcons
} from 'expo-alternate-app-icons';
```
--------------------------------
### Android Icon File Structure
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Shows the directory structure for alternate app icons within an Android project's res folder, including different DPI densities and adaptive icon XML definitions.
```text
android/app/src/main/res/
mipmap-mdpi/
ic_launcher_icon_a.png
ic_launcher_foreground_icon_a.png
ic_launcher_background_icon_a.png
mipmap-hdpi/
ic_launcher_icon_a.png
ic_launcher_foreground_icon_a.png
ic_launcher_background_icon_a.png
(similar for xhdpi, xxhdpi, xxxhdpi)
mipmap-anydpi-v26/
ic_launcher_icon_a.xml
ic_launcher_icon_b.xml
```
--------------------------------
### Check Support and Set Icon
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/quick-reference.md
Conditionally set an alternate app icon after checking for support. Handles potential errors during the process.
```typescript
if (supportsAlternateIcons) {
try {
await setAlternateAppIcon('IconA');
} catch (error) {
console.error('Failed to set icon:', error);
}
}
```
--------------------------------
### Expo Plugin Execution Order
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Illustrates the sequential execution order of modifiers within the Expo Alternate App Icons plugin, showing dependencies between steps like input validation, file generation, and manifest updates.
```plaintext
withAlternateAppIcons()
├─ 1. Input validation & normalization
├─ 2. generateTypeIconsFile() ← Updates src/AlternateAppIconsType.ts
├─ 3. withAlternateAppIconsGenerator() ← iOS icon processing
├─ 4. withXcodeProjectUpdate() ← iOS manifest update
├─ 5. withAdaptiveIconsGenerator() ← Android color + icon processing
└─ 6. withAndroidManifestUpdate() ← Android manifest update
```
--------------------------------
### Runtime Dependencies (JavaScript/TypeScript)
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Visualizes the runtime dependencies within the JavaScript/TypeScript layer of the library, showing how the main entry point, native module wrapper, and platform-specific stubs interact.
```tree
expo-alternate-app-icons (package entry)
├── src/index.ts (exported API)
│ ├── → ExpoAlternateAppIconsModule.ts (wrapper)
│ ├── → ExpoAlternateAppIconsModule.web.ts (platform-specific)
│ └── → AlternateAppIconsType.ts (auto-generated type)
│
└── Native Module Bridge (via Expo Modules Core)
├── → iOS: ExpoAlternateAppIconsModule.swift
└── → Android: ExpoAlternateAppIconsModule.kt
```
--------------------------------
### Create Adaptive Icon XML Definition
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Generates the XML string for an adaptive icon, specifying background, foreground, and optionally monochrome drawables. This XML file is placed in `mipmap-anydpi-v26`.
```typescript
export const createAdaptiveIconXmlString = (
name: string,
backgroundImage?: string,
monochromeImage?: string,
) => { ... }
```
```xml
```
```xml
```
--------------------------------
### createAdaptiveIconXmlString()
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Generates the XML definition string required for adaptive icons, supporting background, foreground, and monochrome layers.
```APIDOC
## createAdaptiveIconXmlString()
### Description
Generates the XML definition for an adaptive icon.
### Method
(string) => string
### Parameters
- **name** (string) - Yes - The name of the icon, used for referencing drawables.
- **backgroundImage** (string) - No - The name of the background drawable resource (e.g., `@mipmap/ic_launcher_background_icon_a`). If not provided, a color resource is used.
- **monochromeImage** (string) - No - The name of the monochrome drawable resource (e.g., `@mipmap/ic_launcher_monochrome_icon_a`).
```
--------------------------------
### Android Adaptive Icon Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Configure the adaptive icon for Android using foreground, background, and monochrome image paths, along with a background color.
```json5
{
"android": {
"foregroundImage": "./assets/icon-foreground.png",
"backgroundColor": "#001413",
"backgroundImage": "./assets/icon-background.png",
"monochromeImage": "./assets/icon-monochrome.png"
}
}
```
--------------------------------
### Plugin Output Interface
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Describes the output structure of the configuration plugin, detailing modifications to iOS and Android configurations, including updated manifests, added color resources, and generated files.
```typescript
interface PluginOutput {
// Modified iOS config
ios: {
// Asset catalogs added/updated
};
// Modified Android config
android: {
// Manifest updated with activity aliases
// Color resources added
};
// Generated files
// src/AlternateAppIconsType.ts (new type definitions)
// iOS icon resources
// Android icon resources
}
```
--------------------------------
### Check Icon Support
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/README.md
Verify if the current device supports alternate app icons.
```ts
const supportsAlternateIcons: boolean;
```
--------------------------------
### Plugin Input Interface
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Defines the expected input structure for the configuration plugin, which includes a 'props' field containing either an array of AlternateIcon objects or an array of strings representing icon names.
```typescript
interface PluginInput {
props: AlternateIcon[] | string[];
}
```
--------------------------------
### React Component for Icon Selection
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/usage-examples.md
Implement a React component to allow users to select and change the app icon. This component checks for device support, displays available icons, and handles the icon switching logic with error handling. It initializes the state with the current icon upon mounting.
```typescript
import React, { useState, useEffect, useCallback } from 'react';
import { View, Text, TouchableOpacity, Alert } from 'react-native';
import {
setAlternateAppIcon,
getAppIconName,
supportsAlternateIcons,
type AlternateAppIcons
} from 'expo-alternate-app-icons';
const AVAILABLE_ICONS: { name: AlternateAppIcons; label: string }[] = [
{ name: 'IconA', label: 'Blue Theme' },
{ name: 'IconB', label: 'Red Theme' },
{ name: 'IconC', label: 'Green Theme' }
];
export function IconPicker() {
const [currentIcon, setCurrentIcon] = useState(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
// Initialize with current icon on mount
const icon = getAppIconName();
setCurrentIcon(icon);
}, []);
const handleIconChange = useCallback(async (iconName: AlternateAppIcons) => {
setIsLoading(true);
try {
await setAlternateAppIcon(iconName);
setCurrentIcon(iconName);
} catch (error) {
if (error instanceof Error) {
Alert.alert('Error', `Failed to change icon: ${error.message}`);
}
} finally {
setIsLoading(false);
}
}, []);
if (!supportsAlternateIcons) {
return This device does not support alternate app icons;
}
return (
Select App Icon
{AVAILABLE_ICONS.map(({ name, label }) => (
handleIconChange(name)}
disabled={isLoading}
style={{
padding: 12,
marginVertical: 8,
backgroundColor: currentIcon === name ? '#4CAF50' : '#E0E0E0',
borderRadius: 8
}}
>
{label}
))}
);
}
```
--------------------------------
### iOS Single Icon Path Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Configures a single icon for all iOS appearance variants (light, dark, tinted) using a simple path.
```json5
{
"ios": "./assets/icon.png"
}
```
--------------------------------
### Handle Configuration Errors
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Missing required properties will cause the processing for that specific icon to be skipped.
```typescript
if (!adaptiveIcon) break;
if (!foregroundImage) break;
```
--------------------------------
### Android DPI Scaling Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/image-generation.md
Defines DPI scaling factors and folder names for generating Android app icons across various screen densities. Includes constants for baseline pixel size and resource paths.
```typescript
type DPIString = 'mdpi' | 'hdpi' | 'xhdpi' | 'xxhdpi' | 'xxxhdpi';
type dpiMap = Record;
const BASELINE_PIXEL_SIZE = 108;
export const ANDROID_RES_PATH = 'android/app/src/main/res/';
const MIPMAP_ANYDPI_V26 = 'mipmap-anydpi-v26';
export const dpiValues: dpiMap = {
mdpi: { folderName: 'mipmap-mdpi', scale: 1 },
hdpi: { folderName: 'mipmap-hdpi', scale: 1.5 },
xhdpi: { folderName: 'mipmap-xhdpi', scale: 2 },
xxhdpi: { folderName: 'mipmap-xxhdpi', scale: 3 },
xxxhdpi: { folderName: 'mipmap-xxxhdpi', scale: 4 },
};
```
--------------------------------
### Android Adaptive Icon Generation Flow
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Outlines the process for generating adaptive icons on Android, including color resources, legacy icons, monochrome images, and adaptive icon layers.
```text
Android Config (AlternateIcon[])
↓
└─ withAdaptiveIconsGenerator()
├─ withAndroidAdaptiveIconColors()
│ └─ Add color resource for each icon background
│
└─ For each icon in alternateIcons:
├─ generateAdaptiveIcon()
│ ├─ Convert name to snake_case
│ ├─ Determine if adaptive (has background/backgroundColor)
│ │
│ ├─ Generate Legacy Icon (all DPIs)
│ │ └─ generateMultiLayerImageAsync()
│ │ ├─ For each DPI (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi):
│ │ │ ├─ Calculate scaled size
│ │ │ ├─ Generate foreground layer (JIMP)
│ │ │ ├─ Generate background layer (if provided)
│ │ │ ├─ Composite layers
│ │ │ └─ Write ic_launcher_.png
│ │ └─ Result: 5 image files (one per DPI)
│ │
│ ├─ Generate Monochrome Image (if provided)
│ │ └─ generateMonochromeImageAsync()
│ │ └─ Write ic_launcher_monochrome_.png (all DPIs)
│ │
│ └─ Generate Adaptive Icon Layers (all DPIs)
│ ├─ Write ic_launcher_foreground_.png
│ ├─ Write ic_launcher_background_.png
│ └─ Write ic_launcher_.xml (adaptive definition)
│
└─ withAndroidManifestUpdate()
└─ Add activity alias for each icon
└─ MainActivity
```
--------------------------------
### iOS Icon Variants by Appearance Configuration
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/configuration.md
Configures separate icons for iOS light, dark, and tinted appearance modes using an object with specific keys.
```json5
{
"ios": {
"light": "./assets/icon-light.png",
"dark": "./assets/icon-dark.png",
"tinted": "./assets/icon-tinted.png"
}
}
```
--------------------------------
### Android Adaptive Icon Configuration Structure
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/types.md
Defines the structure for Android adaptive icon configuration, specifying optional fields for foreground, background, and monochrome images, as well as background color.
```typescript
{
foregroundImage?: string; // Path to foreground image (required)
backgroundColor?: string; // Background color hex (optional)
backgroundImage?: string; // Path to background image (optional)
monochromeImage?: string; // Path to monochrome image (optional)
}
```
--------------------------------
### iOS Icon Generation Data Flow
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/architecture.md
Explains the data flow for generating iOS app icons, covering the steps from initial configuration to the creation of icon assets and the necessary Xcode project updates.
```tree
iOS Config (AlternateIcon[])
↓
└─ withAlternateAppIconsGenerator()
↓
├─ For each icon in alternateIcons:
│ ├─ If ios is string:
│ │ └─ generateUniversalIcon()
│ │ ├─ Load & resize image (JIMP)
│ │ ├─ Create .appiconset directory
│ │ ├─ Write image file
│ │ └─ Write Contents.json
│ │
│ └─ If ios is iOSVariantsIcon:
│ └─ generateUniversalVariantsIcon()
│ ├─ For each variant (light, dark, tinted):
│ │ ├─ Load & resize image
│ │ └─ Write image-.png
│ └─ Write Contents.json (with appearances)
│
└─ withXcodeProjectUpdate()
└─ Update Xcode build property
└─ ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "IconA IconB IconC ..."
```
--------------------------------
### Handle Validation Errors
Source: https://github.com/pchalupa/expo-alternate-app-icons/blob/main/_autodocs/plugin-modifiers.md
Invalid configurations will throw errors, halting the build process.
```typescript
if (!isIosVariantsIcon(iconPath)) {
throw new Error(
`Invalid alternate icon configuration for "${alternateIcon.name}"...
);
}
```