@capawesome/capacitor-app-icon 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @capawesome/capacitor-app-icon
1
+ # Capacitor App Icon Plugin
2
2
 
3
3
  Capacitor plugin to change the app icon at runtime.
4
4
 
@@ -18,9 +18,14 @@ Capacitor plugin to change the app icon at runtime.
18
18
 
19
19
  Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!
20
20
 
21
- ## Newsletter
21
+ ## Use Cases
22
22
 
23
- Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).
23
+ The App Icon plugin is typically used to personalize or refresh the app's appearance on the home screen, for example:
24
+
25
+ - **Seasonal campaigns**: Switch to a themed icon for events like Christmas and restore the default icon afterwards.
26
+ - **Premium personalization**: Let paying users choose their favorite icon from a set of alternate icons.
27
+ - **In-app icon picker**: Build a settings screen that lists all icons and highlights the one currently in use.
28
+ - **Brand updates**: Roll out a new logo as an alternate icon and switch to it at runtime.
24
29
 
25
30
  ## Compatibility
26
31
 
@@ -81,7 +86,7 @@ Open your `AndroidManifest.xml` and remove the launcher `<intent-filter>` from y
81
86
 
82
87
  <!-- An alternate icon (disabled). -->
83
88
  <activity-alias
84
- android:name=".AppIconChristmas"
89
+ android:name=".Christmas"
85
90
  android:enabled="false"
86
91
  android:exported="true"
87
92
  android:icon="@mipmap/ic_launcher_christmas"
@@ -92,36 +97,42 @@ Open your `AndroidManifest.xml` and remove the launcher `<intent-filter>` from y
92
97
  <category android:name="android.intent.category.LAUNCHER" />
93
98
  </intent-filter>
94
99
  </activity-alias>
100
+
101
+ <!-- Another alternate icon (disabled). -->
102
+ <activity-alias
103
+ android:name=".Halloween"
104
+ android:enabled="false"
105
+ android:exported="true"
106
+ android:icon="@mipmap/ic_launcher_halloween"
107
+ android:roundIcon="@mipmap/ic_launcher_halloween_round"
108
+ android:targetActivity=".MainActivity">
109
+ <intent-filter>
110
+ <action android:name="android.intent.action.MAIN" />
111
+ <category android:name="android.intent.category.LAUNCHER" />
112
+ </intent-filter>
113
+ </activity-alias>
95
114
  ```
96
115
 
97
- The icon name passed to `setIcon(...)` is the alias name **without the leading dot** (e.g. `AppIconChristmas`). Add the referenced icon resources (e.g. `@mipmap/ic_launcher_christmas`) to your `res/mipmap-*` folders.
116
+ The icon name passed to `setIcon(...)` is the alias name **without the leading dot** (e.g. `Christmas`). Add the referenced icon resources (e.g. `@mipmap/ic_launcher_christmas`) to your `res/mipmap-*` folders.
98
117
 
99
118
  > [!NOTE]
100
119
  > The behavior after a change depends on the launcher. Some launchers apply the new icon only after the app's task is closed, and a few kill the app despite the plugin requesting otherwise. Shortcuts that were pinned to a now-disabled alias may stop working.
101
120
 
102
121
  ### iOS
103
122
 
104
- On iOS, alternate icons are declared under the `CFBundleIcons` key in your app's `Info.plist`. The icon image files must be bundled with the app (e.g. `AppIconChristmas@2x.png` and `AppIconChristmas@3x.png`).
123
+ On iOS, alternate icons are declared as additional app icon sets in the asset catalog. Add one icon set per alternate icon (e.g. `Christmas` and `Halloween`) next to your primary `AppIcon` in `Assets.xcassets` and register the names (space-separated) in the build settings of your app target:
105
124
 
106
- ```xml
107
- <key>CFBundleIcons</key>
108
- <dict>
109
- <key>CFBundleAlternateIcons</key>
110
- <dict>
111
- <key>AppIconChristmas</key>
112
- <dict>
113
- <key>CFBundleIconFiles</key>
114
- <array>
115
- <string>AppIconChristmas</string>
116
- </array>
117
- <key>UIPrerenderedIcon</key>
118
- <false/>
119
- </dict>
120
- </dict>
121
- </dict>
125
+ ```
126
+ ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "Christmas Halloween";
127
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
122
128
  ```
123
129
 
124
- The icon name passed to `setIcon(...)` is the key inside `CFBundleAlternateIcons` (e.g. `AppIconChristmas`). The default icon (declared via `CFBundlePrimaryIcon` or the asset catalog) is restored with `resetIcon(...)`.
130
+ In Xcode, these settings are called **Alternate App Icon Sets** and **Include All App Icon Assets** in the *Asset Catalog Compiler* section of the build settings.
131
+
132
+ The icon name passed to `setIcon(...)` is the name of the icon set (e.g. `Christmas`), case-sensitive. The primary icon (`AppIcon`) is restored with `resetIcon(...)`.
133
+
134
+ > [!WARNING]
135
+ > Do **not** give an alternate icon set a name that starts with `AppIcon` (e.g. `AppIconChristmas`). In our testing on physical devices running iOS 26, alternate icons whose name shares the primary icon set's `AppIcon` prefix are not rendered on the home screen: `setIcon(...)` succeeds, but the system displays a blank placeholder icon instead of the alternate icon. The iOS Simulator is not affected, so make sure to test on a real device. This is an undocumented iOS behavior; using names without the `AppIcon` prefix is safe on all iOS versions.
125
136
 
126
137
  > [!NOTE]
127
138
  > The system shows a user-visible alert every time the icon changes, and the icon cannot be changed while the app is in the background.
@@ -132,6 +143,12 @@ No configuration required for this plugin.
132
143
 
133
144
  ## Usage
134
145
 
146
+ The following examples show how to check for alternate icon support, read the current icon, set an alternate icon, and reset to the default icon.
147
+
148
+ ### Check if changing the app icon is supported
149
+
150
+ Use `isAvailable()` to check whether the current device supports alternate icons. On Android, this always resolves to `true`; on iOS, it resolves to the value of `supportsAlternateIcons`. Only available on Android and iOS:
151
+
135
152
  ```typescript
136
153
  import { AppIcon } from '@capawesome/capacitor-app-icon';
137
154
 
@@ -139,15 +156,39 @@ const isAvailable = async () => {
139
156
  const { available } = await AppIcon.isAvailable();
140
157
  return available;
141
158
  };
159
+ ```
160
+
161
+ ### Get the current icon
162
+
163
+ Read the name of the icon that is currently in use, for example to highlight it in an icon picker. Returns `null` if the default icon is in use. Only available on Android and iOS:
164
+
165
+ ```typescript
166
+ import { AppIcon } from '@capawesome/capacitor-app-icon';
142
167
 
143
168
  const getCurrentIcon = async () => {
144
169
  const { icon } = await AppIcon.getCurrentIcon();
145
170
  return icon;
146
171
  };
172
+ ```
173
+
174
+ ### Set an alternate icon
175
+
176
+ Change the app icon to an alternate icon that your app has declared beforehand (see [Installation](#installation)). Only available on Android and iOS:
177
+
178
+ ```typescript
179
+ import { AppIcon } from '@capawesome/capacitor-app-icon';
147
180
 
148
181
  const setIcon = async () => {
149
- await AppIcon.setIcon({ icon: 'AppIconChristmas' });
182
+ await AppIcon.setIcon({ icon: 'Christmas' });
150
183
  };
184
+ ```
185
+
186
+ ### Reset to the default icon
187
+
188
+ Restore the default app icon at any time. Only available on Android and iOS:
189
+
190
+ ```typescript
191
+ import { AppIcon } from '@capawesome/capacitor-app-icon';
151
192
 
152
193
  const resetIcon = async () => {
153
194
  await AppIcon.resetIcon();
@@ -232,8 +273,8 @@ setIcon(options: SetIconOptions) => Promise<void>
232
273
  Change the app icon to the alternate icon with the given name.
233
274
 
234
275
  The icon must be declared by the app beforehand. See the setup instructions
235
- for [Android](https://capawesome.io/docs/plugins/app-icon/#android) and
236
- [iOS](https://capawesome.io/docs/plugins/app-icon/#ios) for more information.
276
+ for [Android](https://capawesome.io/docs/sdks/capacitor/app-icon/#android) and
277
+ [iOS](https://capawesome.io/docs/sdks/capacitor/app-icon/#ios) for more information.
237
278
 
238
279
  Only available on Android and iOS.
239
280
 
@@ -265,12 +306,52 @@ Only available on Android and iOS.
265
306
 
266
307
  #### SetIconOptions
267
308
 
268
- | Prop | Type | Description | Since |
269
- | ---------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
270
- | **`icon`** | <code>string</code> | The name of the alternate icon to use. On Android, this is the name of the `&lt;activity-alias&gt;` (without the leading dot). On iOS, this is the key of the icon inside `CFBundleAlternateIcons`. | 0.1.0 |
309
+ | Prop | Type | Description | Since |
310
+ | ---------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
311
+ | **`icon`** | <code>string</code> | The name of the alternate icon to use. On Android, this is the name of the `&lt;activity-alias&gt;` (without the leading dot). On iOS, this is the name of the alternate app icon set in the asset catalog. | 0.1.0 |
271
312
 
272
313
  </docgen-api>
273
314
 
315
+ ## FAQ
316
+
317
+ ### How is this plugin different from other similar plugins?
318
+
319
+ It changes the app icon at runtime on both Android and iOS through one fully typed API — switching to a declared alternate icon, reading the icon currently in use, resetting to the default, and checking whether the device supports alternate icons. It documents the platform realities honestly, from Android's launcher-dependent behavior to the system alert iOS shows on every change, so there are no surprises in production. The plugin is actively maintained against the latest Capacitor and OS versions.
320
+
321
+ ### Can I add new app icons at runtime?
322
+
323
+ No, this plugin cannot add icons dynamically. Every icon you want to switch to must be declared by the app beforehand, as an `<activity-alias>` in the `AndroidManifest.xml` on Android and as an alternate app icon set in the asset catalog on iOS. See the [Installation](#installation) section for detailed setup instructions.
324
+
325
+ ### What icon name do I pass to `setIcon`?
326
+
327
+ On Android, it is the name of the `<activity-alias>` without the leading dot (e.g. `Christmas`). On iOS, it is the name of the alternate app icon set in the asset catalog.
328
+
329
+ ### Why is the new icon not applied immediately on Android?
330
+
331
+ The behavior after a change depends on the launcher. Some launchers apply the new icon only after the app's task is closed, and a few even kill the app despite the plugin requesting otherwise. Also note that shortcuts pinned to a now-disabled alias may stop working.
332
+
333
+ ### Why does iOS show an alert when the icon changes?
334
+
335
+ The system shows a user-visible alert every time the icon changes. This is standard iOS behavior and cannot be suppressed. Also note that the icon cannot be changed while the app is in the background.
336
+
337
+ ### How do I know if the device supports alternate icons?
338
+
339
+ Call `isAvailable()` before offering an icon picker. On Android, it always resolves to `true`. On iOS, it resolves to the value of `supportsAlternateIcons`.
340
+
341
+ ### Can I use this plugin with Ionic, React, Vue or Angular?
342
+
343
+ Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.
344
+
345
+ ## Related Plugins
346
+
347
+ - [App Shortcuts](https://capawesome.io/docs/sdks/capacitor/app-shortcuts/): Manage app shortcuts and quick actions on the home screen.
348
+ - [Badge](https://capawesome.io/docs/sdks/capacitor/badge/): Access and update the badge number of the app icon.
349
+ - [App Update](https://capawesome.io/docs/sdks/capacitor/app-update/): Assist your users with native app updates.
350
+
351
+ ## Newsletter
352
+
353
+ Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).
354
+
274
355
  ## Changelog
275
356
 
276
357
  See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/app-icon/CHANGELOG.md).
@@ -30,7 +30,7 @@ android {
30
30
  buildTypes {
31
31
  release {
32
32
  minifyEnabled false
33
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
33
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
34
34
  }
35
35
  }
36
36
  lintOptions {
package/dist/docs.json CHANGED
@@ -71,7 +71,7 @@
71
71
  "text": "0.1.0"
72
72
  }
73
73
  ],
74
- "docs": "Change the app icon to the alternate icon with the given name.\n\nThe icon must be declared by the app beforehand. See the setup instructions\nfor [Android](https://capawesome.io/docs/plugins/app-icon/#android) and\n[iOS](https://capawesome.io/docs/plugins/app-icon/#ios) for more information.\n\nOnly available on Android and iOS.",
74
+ "docs": "Change the app icon to the alternate icon with the given name.\n\nThe icon must be declared by the app beforehand. See the setup instructions\nfor [Android](https://capawesome.io/docs/sdks/capacitor/app-icon/#android) and\n[iOS](https://capawesome.io/docs/sdks/capacitor/app-icon/#ios) for more information.\n\nOnly available on Android and iOS.",
75
75
  "complexTypes": [
76
76
  "SetIconOptions"
77
77
  ],
@@ -97,7 +97,7 @@
97
97
  "name": "icon",
98
98
  "tags": [
99
99
  {
100
- "text": "'AppIconChristmas'",
100
+ "text": "'Christmas'",
101
101
  "name": "example"
102
102
  },
103
103
  {
@@ -153,7 +153,7 @@
153
153
  "name": "icon",
154
154
  "tags": [
155
155
  {
156
- "text": "'AppIconChristmas'",
156
+ "text": "'Christmas'",
157
157
  "name": "example"
158
158
  },
159
159
  {
@@ -161,7 +161,7 @@
161
161
  "name": "since"
162
162
  }
163
163
  ],
164
- "docs": "The name of the alternate icon to use.\n\nOn Android, this is the name of the `<activity-alias>` (without the leading dot).\nOn iOS, this is the key of the icon inside `CFBundleAlternateIcons`.",
164
+ "docs": "The name of the alternate icon to use.\n\nOn Android, this is the name of the `<activity-alias>` (without the leading dot).\nOn iOS, this is the name of the alternate app icon set in the asset catalog.",
165
165
  "complexTypes": [],
166
166
  "type": "string"
167
167
  }
@@ -32,8 +32,8 @@ export interface AppIconPlugin {
32
32
  * Change the app icon to the alternate icon with the given name.
33
33
  *
34
34
  * The icon must be declared by the app beforehand. See the setup instructions
35
- * for [Android](https://capawesome.io/docs/plugins/app-icon/#android) and
36
- * [iOS](https://capawesome.io/docs/plugins/app-icon/#ios) for more information.
35
+ * for [Android](https://capawesome.io/docs/sdks/capacitor/app-icon/#android) and
36
+ * [iOS](https://capawesome.io/docs/sdks/capacitor/app-icon/#ios) for more information.
37
37
  *
38
38
  * Only available on Android and iOS.
39
39
  *
@@ -50,7 +50,7 @@ export interface GetCurrentIconResult {
50
50
  *
51
51
  * Returns `null` if the default icon is in use.
52
52
  *
53
- * @example 'AppIconChristmas'
53
+ * @example 'Christmas'
54
54
  * @since 0.1.0
55
55
  */
56
56
  icon: string | null;
@@ -74,9 +74,9 @@ export interface SetIconOptions {
74
74
  * The name of the alternate icon to use.
75
75
  *
76
76
  * On Android, this is the name of the `<activity-alias>` (without the leading dot).
77
- * On iOS, this is the key of the icon inside `CFBundleAlternateIcons`.
77
+ * On iOS, this is the name of the alternate app icon set in the asset catalog.
78
78
  *
79
- * @example 'AppIconChristmas'
79
+ * @example 'Christmas'
80
80
  * @since 0.1.0
81
81
  */
82
82
  icon: string;
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAuFA;;GAEG;AACH,MAAM,CAAN,IAAY,SAaX;AAbD,WAAY,SAAS;IACnB;;;;OAIG;IACH,2CAA8B,CAAA;IAC9B;;;;OAIG;IACH,4CAA+B,CAAA;AACjC,CAAC,EAbW,SAAS,KAAT,SAAS,QAapB","sourcesContent":["export interface AppIconPlugin {\n /**\n * Get the name of the icon that is currently in use.\n *\n * Returns `null` if the default icon is in use.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n getCurrentIcon(): Promise<GetCurrentIconResult>;\n /**\n * Check if changing the app icon is supported on the current device.\n *\n * On Android, this always resolves to `true`.\n * On iOS, this resolves to the value of `supportsAlternateIcons`.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n isAvailable(): Promise<IsAvailableResult>;\n /**\n * Restore the default app icon.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n resetIcon(): Promise<void>;\n /**\n * Change the app icon to the alternate icon with the given name.\n *\n * The icon must be declared by the app beforehand. See the setup instructions\n * for [Android](https://capawesome.io/docs/plugins/app-icon/#android) and\n * [iOS](https://capawesome.io/docs/plugins/app-icon/#ios) for more information.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n setIcon(options: SetIconOptions): Promise<void>;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface GetCurrentIconResult {\n /**\n * The name of the icon that is currently in use.\n *\n * Returns `null` if the default icon is in use.\n *\n * @example 'AppIconChristmas'\n * @since 0.1.0\n */\n icon: string | null;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface IsAvailableResult {\n /**\n * Whether or not changing the app icon is supported on the current device.\n *\n * @since 0.1.0\n */\n available: boolean;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface SetIconOptions {\n /**\n * The name of the alternate icon to use.\n *\n * On Android, this is the name of the `<activity-alias>` (without the leading dot).\n * On iOS, this is the key of the icon inside `CFBundleAlternateIcons`.\n *\n * @example 'AppIconChristmas'\n * @since 0.1.0\n */\n icon: string;\n}\n\n/**\n * @since 0.1.0\n */\nexport enum ErrorCode {\n /**\n * The app icon could not be changed.\n *\n * @since 0.1.0\n */\n ChangeFailed = 'CHANGE_FAILED',\n /**\n * The alternate icon with the given name could not be found.\n *\n * @since 0.1.0\n */\n IconNotFound = 'ICON_NOT_FOUND',\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAuFA;;GAEG;AACH,MAAM,CAAN,IAAY,SAaX;AAbD,WAAY,SAAS;IACnB;;;;OAIG;IACH,2CAA8B,CAAA;IAC9B;;;;OAIG;IACH,4CAA+B,CAAA;AACjC,CAAC,EAbW,SAAS,KAAT,SAAS,QAapB","sourcesContent":["export interface AppIconPlugin {\n /**\n * Get the name of the icon that is currently in use.\n *\n * Returns `null` if the default icon is in use.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n getCurrentIcon(): Promise<GetCurrentIconResult>;\n /**\n * Check if changing the app icon is supported on the current device.\n *\n * On Android, this always resolves to `true`.\n * On iOS, this resolves to the value of `supportsAlternateIcons`.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n isAvailable(): Promise<IsAvailableResult>;\n /**\n * Restore the default app icon.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n resetIcon(): Promise<void>;\n /**\n * Change the app icon to the alternate icon with the given name.\n *\n * The icon must be declared by the app beforehand. See the setup instructions\n * for [Android](https://capawesome.io/docs/sdks/capacitor/app-icon/#android) and\n * [iOS](https://capawesome.io/docs/sdks/capacitor/app-icon/#ios) for more information.\n *\n * Only available on Android and iOS.\n *\n * @since 0.1.0\n */\n setIcon(options: SetIconOptions): Promise<void>;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface GetCurrentIconResult {\n /**\n * The name of the icon that is currently in use.\n *\n * Returns `null` if the default icon is in use.\n *\n * @example 'Christmas'\n * @since 0.1.0\n */\n icon: string | null;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface IsAvailableResult {\n /**\n * Whether or not changing the app icon is supported on the current device.\n *\n * @since 0.1.0\n */\n available: boolean;\n}\n\n/**\n * @since 0.1.0\n */\nexport interface SetIconOptions {\n /**\n * The name of the alternate icon to use.\n *\n * On Android, this is the name of the `<activity-alias>` (without the leading dot).\n * On iOS, this is the name of the alternate app icon set in the asset catalog.\n *\n * @example 'Christmas'\n * @since 0.1.0\n */\n icon: string;\n}\n\n/**\n * @since 0.1.0\n */\nexport enum ErrorCode {\n /**\n * The app icon could not be changed.\n *\n * @since 0.1.0\n */\n ChangeFailed = 'CHANGE_FAILED',\n /**\n * The alternate icon with the given name could not be found.\n *\n * @since 0.1.0\n */\n IconNotFound = 'ICON_NOT_FOUND',\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capawesome/capacitor-app-icon",
3
- "version": "0.0.1",
4
- "description": "Capacitor plugin to change the app icon at runtime.",
3
+ "version": "0.1.1",
4
+ "description": "Capacitor plugin to change the app icon at runtime on Android and iOS.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",
@@ -33,11 +33,19 @@
33
33
  "url": "https://opencollective.com/capawesome"
34
34
  }
35
35
  ],
36
- "homepage": "https://capawesome.io/docs/plugins/app-icon/",
36
+ "homepage": "https://capawesome.io/docs/sdks/capacitor/app-icon/",
37
37
  "keywords": [
38
38
  "capacitor",
39
39
  "plugin",
40
- "native"
40
+ "native",
41
+ "capacitor-plugin",
42
+ "app icon",
43
+ "alternate icon",
44
+ "change app icon",
45
+ "dynamic app icon",
46
+ "custom app icon",
47
+ "icon switcher",
48
+ "launcher icon"
41
49
  ],
42
50
  "scripts": {
43
51
  "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",