Skip to content

Commit 5859908

Browse files
docs: updated readme
1 parent 01d29ec commit 5859908

File tree

1 file changed

+268
-45
lines changed

1 file changed

+268
-45
lines changed

example/README.md

Lines changed: 268 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,302 @@
1-
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
1+
# @computools/react-native-dynamic-app-icon 🚀
22

3-
# Getting Started
3+
Dynamically change the app icon in React Native with cross-platform support for iOS and Android. Perfect for themes, events, and personalization.
44

5-
>**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.
5+
<table>
6+
<tr>
7+
<th style="text-align: center;">iOS</th>
8+
<th style="text-align: center;">Android</th>
9+
</tr>
10+
<tr>
11+
<td>
12+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/ios_dynamic_app_icon_preview.gif?updatedAt=1737115408393" width="300">
13+
</td>
14+
<td">
15+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/android_dynamic_app_icon_preview.gif?updatedAt=1737115956222" width="300">
16+
</td>
17+
</tr>
18+
</table>
619

7-
## Step 1: Start the Metro Server
20+
## Installation
821

9-
First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.
22+
**Using Yarn**
1023

11-
To start Metro, run the following command from the _root_ of your React Native project:
24+
```bash
25+
yarn add @computools/react-native-dynamic-app-icon
26+
```
27+
28+
**Using npm**
1229

1330
```bash
14-
# using npm
15-
npm start
31+
npm i @computools/react-native-dynamic-app-icon
32+
```
33+
### iOS Set Up
1634

17-
# OR using Yarn
18-
yarn start
35+
After installing the package, run:
36+
37+
```bash
38+
cd ios
39+
pod install
1940
```
2041

21-
## Step 2: Start your Application
42+
## Generate App Icons
2243

23-
Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app:
44+
Generate app icons using a tool like [appicon.co](https://www.appicon.co/) to ensure all required sizes and formats are included.
2445

25-
### For Android
46+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/app_icon_generator.png?updatedAt=1737458948009" width="400"/>
2647

27-
```bash
28-
# using npm
29-
npm run android
48+
## App Icons Set Up
49+
50+
### Android
3051

31-
# OR using Yarn
32-
yarn android
52+
#### Step 1: Add App Icons Files
53+
54+
1. Rename generated files to *ic_launcher_<icon_type>.png* e.g. `ic_launcher_orange.png`.
55+
2. Rename default icon files to to `ic_launcher_default.png`
56+
3. Move app icons files to `android/app/src/main/res/mipmap-*`.
57+
58+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/icons_files_android.png?updatedAt=1737456324691" width="400">
59+
60+
#### Step 2: Modify `AndroidManifest.xml`
61+
62+
1. Add activity-alias for each icon.
63+
64+
```kotlin
65+
<activity-alias
66+
android:name=".MainActivityPineapple" // .MainActivity + <icon-type>
67+
android:enabled="false"
68+
android:exported="true"
69+
android:icon="@mipmap/ic_launcher_pineapple"
70+
android:targetActivity=".MainActivity">
71+
<intent-filter>
72+
<action android:name="android.intent.action.MAIN" />
73+
<category android:name="android.intent.category.LAUNCHER" />
74+
</intent-filter>
75+
</activity-alias>
3376
```
3477

35-
### For iOS
78+
**Important**: `android:enabled="true"` should be only for **default** activity-alias, other should have `android:enabled="false"`.
3679

37-
```bash
38-
# using npm
39-
npm run ios
80+
2. Remove `<category android:name="android.intent.category.LAUNCHER" />` for activity-alias with `android:enabled="true"`.
81+
82+
**Notes:**
83+
1. Don’t forget to use the correct file for `android:icon` and `android:name`. `android:name` is **.MainActivity + <icon-type>** e.g for `android:icon=ic_launcher_orange` `android:name=".MainActivityOrange"`.
84+
2. Don't forget to change `android:icon` to `"@mipmap/ic_launcher_default"` in `<application>` tag.
85+
3. Make sure you have activity-alias with `android:icon=ic_launcher_default`, `android:name=".MainActivityDefault"`.
86+
87+
**`AndroidManifest.xml` example:**
4088

41-
# OR using Yarn
42-
yarn ios
89+
```kotlin
90+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
91+
92+
<uses-permission android:name="android.permission.INTERNET" />
93+
94+
<application
95+
android:name=".MainApplication"
96+
android:label="@string/app_name"
97+
android:icon="@mipmap/ic_launcher_default"
98+
android:allowBackup="false"
99+
android:theme="@style/AppTheme"
100+
android:supportsRtl="true">
101+
<activity
102+
android:name=".MainActivity"
103+
android:label="@string/app_name"
104+
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
105+
android:launchMode="singleTask"
106+
android:windowSoftInputMode="adjustResize"
107+
android:exported="true">
108+
<intent-filter>
109+
<action android:name="android.intent.action.MAIN" />
110+
<category android:name="android.intent.category.LAUNCHER" />
111+
</intent-filter>
112+
</activity>
113+
<activity-alias
114+
android:name=".MainActivityDefault"
115+
android:enabled="true"
116+
android:exported="true"
117+
android:icon="@mipmap/ic_launcher_default"
118+
android:targetActivity=".MainActivity">
119+
<intent-filter>
120+
<action android:name="android.intent.action.MAIN" />
121+
</intent-filter>
122+
</activity-alias>
123+
<activity-alias
124+
android:name=".MainActivityPineapple"
125+
android:enabled="false"
126+
android:exported="true"
127+
android:icon="@mipmap/ic_launcher_pineapple"
128+
android:targetActivity=".MainActivity">
129+
<intent-filter>
130+
<action android:name="android.intent.action.MAIN" />
131+
<category android:name="android.intent.category.LAUNCHER" />
132+
</intent-filter>
133+
</activity-alias>
134+
<activity-alias
135+
android:name=".MainActivityStrawberry"
136+
android:enabled="false"
137+
android:exported="true"
138+
android:icon="@mipmap/ic_launcher_strawberry"
139+
android:targetActivity=".MainActivity">
140+
<intent-filter>
141+
<action android:name="android.intent.action.MAIN" />
142+
<category android:name="android.intent.category.LAUNCHER" />
143+
</intent-filter>
144+
</activity-alias>
145+
<activity-alias
146+
android:name=".MainActivityOrange"
147+
android:enabled="false"
148+
android:exported="true"
149+
android:icon="@mipmap/ic_launcher_orange"
150+
android:targetActivity=".MainActivity">
151+
<intent-filter>
152+
<action android:name="android.intent.action.MAIN" />
153+
<category android:name="android.intent.category.LAUNCHER" />
154+
</intent-filter>
155+
</activity-alias>
156+
</application>
157+
</manifest>
43158
```
44159

45-
If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly.
160+
### iOS
161+
162+
#### Step 1: Add App Icons Files
163+
164+
1. Rename generated `AppIcon.appiconset` folders to `<icon-type>Icon.appiconset`.
165+
2. Rename default `AppIcon.appiconset` to `DefaultIcon.appiconset`.
166+
3. Move all .appiconset folders into `ios/<app-name>/Images.xcassets`.
167+
4. Update `folder` values in each `Contents.json` file e.g `"folder": "Images.xcassets/PineappleIcon.appiconset/"`.
46168

47-
This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively.
169+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/icons_files_ios.png?updatedAt=1737456324725" width="400">
48170

49-
## Step 3: Modifying your App
171+
#### Step 2: Set up App Icon in Xcode
50172

51-
Now that you have successfully run the app, let's modify it.
173+
1. Open Xcode;
174+
2. Go to app's `General` settings;
175+
3. Scroll to `App Icons and Launch Screen`;
176+
4. Set `App Icon` to *`DefaultIcon`* and check the `Include all app icon assets` checkbox below.
52177

53-
1. Open `App.tsx` in your text editor of choice and edit some lines.
54-
2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes!
178+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/xcode_general.png?updatedAt=1737456324703" width="400">
55179

56-
For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes!
180+
#### Step 3: Modify Info.plist
57181

58-
## Congratulations! :tada:
182+
1. Open Xcode, go to `Info` and insert a key for `CFBundleIcons.`
183+
2. Within `CFBundleIcons` dictionary add key `CFBundleAlternateIcons`.
184+
3. Within `CFBundleAlternateIcons` add keys for alternative icons:
185+
- The `key` is the name you will reference from within code.
186+
- Set the first `array` item to the name of the target .appiconset.
187+
4. Within `CFBundleIcons` set the default icon name in `CFBundlePrimaryIcon` and `UINewsstandIcon` -> Icon files -> Item 0.
59188

60-
You've successfully run and modified your React Native App. :partying_face:
189+
<img src="https://ik.imagekit.io/Computools/RN%20Dynamic%20App%20Icons%20/info_plist.png?updatedAt=1737456324778" width="400">
61190

62-
### Now what?
191+
<br />
192+
193+
**`Info.plist` example:**
194+
195+
```
196+
<key>CFBundleIcons</key>
197+
<dict>
198+
<key>CFBundleAlternateIcons</key>
199+
<dict>
200+
<key>DefaultIcon</key>
201+
<dict>
202+
<key>CFBundleIconFiles</key>
203+
<array>
204+
<string>DefaultIcon</string>
205+
</array>
206+
<key>UIPrerenderedIcon</key>
207+
<false/>
208+
</dict>
209+
<key>OrangeIcon</key>
210+
<dict>
211+
<key>CFBundleIconFiles</key>
212+
<array>
213+
<string>OrangeIcon</string>
214+
</array>
215+
<key>UIPrerenderedIcon</key>
216+
<false/>
217+
</dict>
218+
<key>PineappleIcon</key>
219+
<dict>
220+
<key>CFBundleIconFiles</key>
221+
<array>
222+
<string>PineappleIcon</string>
223+
</array>
224+
<key>UIPrerenderedIcon</key>
225+
<false/>
226+
</dict>
227+
<key>StrawberryIcon</key>
228+
<dict>
229+
<key>CFBundleIconFiles</key>
230+
<array>
231+
<string>StrawberryIcon</string>
232+
</array>
233+
<key>UIPrerenderedIcon</key>
234+
<false/>
235+
</dict>
236+
</dict>
237+
<key>CFBundlePrimaryIcon</key>
238+
<dict>
239+
<key>CFBundleIconFiles</key>
240+
<array>
241+
<string>DefaultIcon</string>
242+
</array>
243+
<key>CFBundleIconName</key>
244+
<string></string>
245+
<key>UIPrerenderedIcon</key>
246+
<false/>
247+
</dict>
248+
<key>UINewsstandIcon</key>
249+
<dict>
250+
<key>CFBundleIconFiles</key>
251+
<array>
252+
<string>DefaultIcon</string>
253+
</array>
254+
<key>UINewsstandBindingEdge</key>
255+
<string>UINewsstandBindingEdgeLeft</string>
256+
<key>UINewsstandBindingType</key>
257+
<string>UINewsstandBindingTypeMagazine</string>
258+
</dict>
259+
</dict>
260+
```
63261

64-
- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
65-
- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started).
262+
## Methods
66263

67-
# Troubleshooting
264+
Method | Description | Parameters | Returns |
265+
--- | --- | --- | --- |
266+
**changeIcon(iconName: string)** | Changes the app's icon to the specified icon. <br/> **Note:** The package automatically closes the app on Android after changing the app icon. This behavior is implemented to prevent duplicate icons and requires no additional action from the user. | iconName (string): The name of the icon to switch to. | `Promise<void>`: Resolves with void or rejects with an error. |
267+
**getIcon()** | Retrieves the name of the currently active app icon. | None | `Promise<string>`: Resolves with the name of the current used icon or rejects with an error. |
68268

69-
If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
269+
## Usage
70270

71-
# Learn More
271+
### Change Icon
72272

73-
To learn more about React Native, take a look at the following resources:
273+
```typescript
274+
import { changeIcon } from '@computools/react-native-dynamic-app-icon';
74275

75-
- [React Native Website](https://reactnative.dev) - learn more about React Native.
76-
- [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
77-
- [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
78-
- [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
79-
- [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
276+
const setAppIcon = async () => {
277+
try {
278+
await changeIcon('Orange');
279+
} catch (error) {
280+
// error handling
281+
}
282+
}
283+
284+
setAppIcon();
285+
```
286+
287+
### Get Icon
288+
289+
```typescript
290+
import { getIcon } from '@computools/react-native-dynamic-app-icon';
291+
292+
const getCurrentIcon = async () => {
293+
try {
294+
const currentIcon = await getIcon();
295+
// the logic of saving the currentIcon or other
296+
} catch (error) {
297+
// error handling
298+
}
299+
}
300+
301+
getCurrentIcon();
302+
```

0 commit comments

Comments
 (0)