react-native-notify-kit 10.3.3 → 10.4.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 +102 -12
- package/app.plugin.js +3 -0
- package/cli/dist/commands/initNse.js +8 -9
- package/cli/dist/commands/initNse.js.map +1 -1
- package/cli/dist/lib/detectProject.d.ts +1 -4
- package/cli/dist/lib/detectProject.js +3 -32
- package/cli/dist/lib/detectProject.js.map +1 -1
- package/cli/dist/lib/initNseCore.d.ts +8 -0
- package/cli/dist/lib/initNseCore.js +197 -0
- package/cli/dist/lib/initNseCore.js.map +1 -0
- package/cli/dist/lib/patchPodfile.d.ts +9 -0
- package/cli/dist/lib/patchPodfile.js +22 -15
- package/cli/dist/lib/patchPodfile.js.map +1 -1
- package/cli/dist/lib/patchXcodeProject.d.ts +16 -0
- package/cli/dist/lib/patchXcodeProject.js +54 -26
- package/cli/dist/lib/patchXcodeProject.js.map +1 -1
- package/cli/dist/lib/writeTemplates.js +5 -14
- package/cli/dist/lib/writeTemplates.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/ios/RNNotifee/NotifeeApiModule.h +1 -2
- package/ios/RNNotifee/NotifeeApiModule.mm +4 -0
- package/ios/RNNotifee/NotifeeExtensionHelper.h +2 -2
- package/ios/RNNotifee/NotifeeExtensionHelper.m +1 -0
- package/package.json +15 -2
- package/plugin/build/android/withNotifyKitAndroidManifest.js +236 -0
- package/plugin/build/index.js +62 -0
- package/plugin/build/ios/withNotifyKitIosNseAppExtension.js +142 -0
- package/plugin/build/ios/withNotifyKitIosNseFiles.js +79 -0
- package/plugin/build/ios/withNotifyKitIosNsePodfile.js +130 -0
- package/plugin/build/ios/withNotifyKitIosNseXcodeProject.js +49 -0
- package/plugin/build/options.js +224 -0
- package/plugin/build/shared/nse/index.js +7 -0
- package/plugin/build/shared/nse/initNseCore.js +220 -0
- package/plugin/build/shared/nse/patchPodfile.js +261 -0
- package/plugin/build/shared/nse/patchXcodeProject.js +199 -0
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
# react-native-notify-kit
|
|
7
7
|
|
|
8
|
-
Maintained Notifee-compatible fork: a feature-rich React Native notification library
|
|
8
|
+
Maintained Notifee-compatible fork: a feature-rich React Native notification library for Android, iOS, FCM Mode, and Expo CNG development builds.
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
11
|
<a href="https://www.npmjs.com/package/react-native-notify-kit"><img src="https://img.shields.io/npm/v/react-native-notify-kit.svg" alt="npm version"></a>
|
|
@@ -17,7 +17,7 @@ Maintained Notifee-compatible fork: a feature-rich React Native notification lib
|
|
|
17
17
|
|
|
18
18
|
<hr/>
|
|
19
19
|
|
|
20
|
-
> 📘 **Full documentation:** [docs.page/marcocrupi/react-native-notify-kit](https://docs.page/marcocrupi/react-native-notify-kit/react-native/overview)
|
|
20
|
+
> 📘 **Full documentation:** [docs.page/marcocrupi/react-native-notify-kit](https://docs.page/marcocrupi/react-native-notify-kit/react-native/overview) - public API reference, platform guides, FCM Mode, Expo CNG setup, server SDK, config plugin, and the `init-nse` CLI.
|
|
21
21
|
|
|
22
22
|
An actively maintained fork of Notifee for React Native notifications, continued and improved by Marco Crupi.
|
|
23
23
|
|
|
@@ -35,7 +35,7 @@ However, `expo-notifications` does not cover several advanced capabilities that
|
|
|
35
35
|
- **Full-screen intent notifications** (alarm/call screens)
|
|
36
36
|
- **Ongoing / persistent notifications**
|
|
37
37
|
|
|
38
|
-
This fork fills the gap: it preserves all of Notifee's advanced features, migrates the bridge to React Native's **New Architecture** (TurboModules), and actively fixes the critical bugs left unresolved upstream
|
|
38
|
+
This fork fills the gap: it preserves all of Notifee's advanced features, migrates the bridge to React Native's **New Architecture** (TurboModules), and actively fixes the critical bugs left unresolved upstream. See the [bug fix table](#bugs-fixed-from-upstream-notifee) below. It also supports Expo CNG / prebuild development builds through an official config plugin. Expo Go is not supported.
|
|
39
39
|
|
|
40
40
|
## Project Status
|
|
41
41
|
|
|
@@ -44,6 +44,10 @@ This fork fills the gap: it preserves all of Notifee's advanced features, migrat
|
|
|
44
44
|
- Officially recommended by Invertase as the community-maintained fork (April 2026)
|
|
45
45
|
- Maintained fork of Notifee — actively developed and published as `react-native-notify-kit`
|
|
46
46
|
- New Architecture only (TurboModules)
|
|
47
|
+
- Expo CNG / prebuild support for development builds. Expo Go is not supported.
|
|
48
|
+
- iOS FCM Mode Notification Service Extension automation via config plugin.
|
|
49
|
+
- Android foreground service manifest configuration via config plugin, with explicit opt-in for foreground service types.
|
|
50
|
+
- Android Expo FCM smoke validation using RNFirebase data-only messages and `notifee.handleFcmMessage`.
|
|
47
51
|
- Minimum supported React Native: `0.73`
|
|
48
52
|
- Development target: React Native `0.84`
|
|
49
53
|
- License: `Apache-2.0`
|
|
@@ -150,9 +154,9 @@ useEffect(() => {
|
|
|
150
154
|
>
|
|
151
155
|
> Register **both** handlers if you need to react to taps in every app state. Resolves the confusion reported in upstream [invertase/notifee#1155](https://github.com/invertase/notifee/issues/1155).
|
|
152
156
|
|
|
153
|
-
## Notifee FCM Mode (NEW in 10.0.0)
|
|
157
|
+
## Notifee FCM Mode (NEW in 10.0.0, Expo CNG in 10.4.0)
|
|
154
158
|
|
|
155
|
-
**Use `react-native-notify-kit` as the sole FCM display layer on both Android and iOS
|
|
159
|
+
**Use `react-native-notify-kit` as the sole FCM display layer on both Android and iOS**: one developer API, no duplicate notifications on Android, no silent-push drops on iOS. Ship a server SDK payload, let the client handle it in one line, and set up the iOS Notification Service Extension with the Expo config plugin or, for bare React Native, the `init-nse` CLI. On Android, FCM Mode remains data-only: RNFirebase receives the message and calls `notifee.handleFcmMessage`.
|
|
156
160
|
|
|
157
161
|
```bash
|
|
158
162
|
# server: build the payload
|
|
@@ -162,16 +166,71 @@ await admin.messaging().send(buildNotifyKitPayload({ token, notification: { titl
|
|
|
162
166
|
# client (Android + iOS): one line in setBackgroundMessageHandler / onMessage
|
|
163
167
|
await notifee.handleFcmMessage(remoteMessage);
|
|
164
168
|
|
|
165
|
-
# iOS NSE
|
|
169
|
+
# iOS NSE setup for bare React Native
|
|
166
170
|
npx react-native-notify-kit init-nse && cd ios && pod install
|
|
167
171
|
```
|
|
168
172
|
|
|
173
|
+
### Expo CNG / development builds
|
|
174
|
+
|
|
175
|
+
Expo CNG / development builds are supported. Expo Go is not supported because this library requires native modules and native notification targets/capabilities.
|
|
176
|
+
|
|
177
|
+
On iOS, add the config plugin to your Expo config and run prebuild; the plugin generates and wires the Notification Service Extension used by NotifyKit FCM Mode.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
export default {
|
|
181
|
+
expo: {
|
|
182
|
+
name: 'MyApp',
|
|
183
|
+
slug: 'my-app',
|
|
184
|
+
ios: {
|
|
185
|
+
bundleIdentifier: 'com.example.myapp',
|
|
186
|
+
},
|
|
187
|
+
plugins: [
|
|
188
|
+
[
|
|
189
|
+
'react-native-notify-kit',
|
|
190
|
+
{
|
|
191
|
+
ios: {
|
|
192
|
+
notificationServiceExtension: true,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
On Android, FCM Mode stays data-only. Configure Firebase and RNFirebase in the app, create the Android channel used by your payloads, then call `notifee.handleFcmMessage(remoteMessage)` from RNFirebase `onMessage` and `setBackgroundMessageHandler`. The Expo smoke app validates foreground and background delivery with the `android-expo-smoke` scenario on a real device.
|
|
202
|
+
|
|
203
|
+
Android foreground service manifest configuration is also available through the NotifyKit config plugin, but it is explicit opt-in:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
export default {
|
|
207
|
+
expo: {
|
|
208
|
+
plugins: [
|
|
209
|
+
[
|
|
210
|
+
'react-native-notify-kit',
|
|
211
|
+
{
|
|
212
|
+
android: {
|
|
213
|
+
foregroundService: {
|
|
214
|
+
types: ['shortService'],
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The plugin does not configure Firebase, does not add `USE_EXACT_ALARM`, does not add `USE_FULL_SCREEN_INTENT`, and does not choose a foreground service type by default.
|
|
225
|
+
|
|
169
226
|
See the full guide: **[docs/fcm-mode.mdx](docs/fcm-mode.mdx)** — covers architecture, server SDK reference, client API, NSE setup, payload schema, migration, troubleshooting, and known limitations.
|
|
170
227
|
|
|
171
228
|
## Push Notifications (Firebase)
|
|
172
229
|
|
|
173
230
|
This library handles notification **display and management**. For receiving push notifications, pair it with [`@react-native-firebase/messaging`](https://rnfirebase.io/messaging/usage):
|
|
174
231
|
|
|
232
|
+
Firebase setup remains the consumer app's responsibility. The NotifyKit Expo config plugin does not install or configure Firebase, does not copy `google-services.json`, and does not patch Gradle for Firebase.
|
|
233
|
+
|
|
175
234
|
> **New in 10.0.0:** for a turnkey FCM integration that handles both platforms (no duplicate on Android, APNs-reliable on iOS), use **[Notifee FCM Mode](docs/fcm-mode.mdx)** instead of the manual pattern below. The sections that follow still apply for basic Firebase setup (google-services plugin, permissions, APNs capability).
|
|
176
235
|
|
|
177
236
|
### Android setup
|
|
@@ -231,9 +290,37 @@ messaging().onMessage(async remoteMessage => {
|
|
|
231
290
|
|
|
232
291
|
## iOS Notification Service Extension
|
|
233
292
|
|
|
234
|
-
To modify push notification content before display (e.g., attach images), create a Notification Service Extension.
|
|
293
|
+
To modify push notification content before display (e.g., attach images), create a Notification Service Extension. FCM Mode supports two automated setup paths: Expo CNG uses the config plugin, while bare React Native uses the `init-nse` CLI.
|
|
235
294
|
|
|
236
|
-
###
|
|
295
|
+
### Expo CNG automated setup
|
|
296
|
+
|
|
297
|
+
Use this for Expo prebuild / development builds:
|
|
298
|
+
|
|
299
|
+
```ts
|
|
300
|
+
export default {
|
|
301
|
+
expo: {
|
|
302
|
+
name: 'MyApp',
|
|
303
|
+
slug: 'my-app',
|
|
304
|
+
ios: {
|
|
305
|
+
bundleIdentifier: 'com.example.myapp',
|
|
306
|
+
},
|
|
307
|
+
plugins: [
|
|
308
|
+
[
|
|
309
|
+
'react-native-notify-kit',
|
|
310
|
+
{
|
|
311
|
+
ios: {
|
|
312
|
+
notificationServiceExtension: true,
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
],
|
|
316
|
+
],
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Run Expo prebuild or an EAS development build after adding the plugin. The plugin adds the EAS `appExtensions` entry and generates the Swift service, `Info.plist`, entitlements, Xcode target, `.appex` embed phase, and Podfile target. Expo Go is not supported.
|
|
322
|
+
|
|
323
|
+
### Bare React Native automated setup
|
|
237
324
|
|
|
238
325
|
From your project root, with `react-native-notify-kit` installed:
|
|
239
326
|
|
|
@@ -242,11 +329,11 @@ npx react-native-notify-kit init-nse
|
|
|
242
329
|
cd ios && pod install
|
|
243
330
|
```
|
|
244
331
|
|
|
245
|
-
The CLI scaffolds a Swift NSE target (default name: `NotifyKitNSE`), patches your Podfile, and wires `.pbxproj`. Open your `.xcworkspace` in Xcode, verify the NSE target's signing, and build. See [docs/fcm-mode.mdx#ios-nse-setup](docs/fcm-mode.mdx#ios-nse-setup) for the full CLI reference (target name, bundle suffix, `--dry-run`, `--force`).
|
|
332
|
+
The CLI scaffolds a Swift NSE target (default name: `NotifyKitNSE`), patches your Podfile, and wires `.pbxproj`. Open your `.xcworkspace` in Xcode, verify the NSE target's signing, and build. Expo users should use the config plugin instead of running `init-nse` against generated native folders. See [docs/fcm-mode.mdx#ios-nse-setup](docs/fcm-mode.mdx#ios-nse-setup) for the full CLI reference (target name, bundle suffix, `--dry-run`, `--force`).
|
|
246
333
|
|
|
247
334
|
### Manual setup
|
|
248
335
|
|
|
249
|
-
For
|
|
336
|
+
For bare React Native projects with non-standard iOS paths or heavily-customized Xcode configurations where automation cannot patch the project cleanly:
|
|
250
337
|
|
|
251
338
|
1. In Xcode: **File > New > Target > Notification Service Extension**
|
|
252
339
|
2. Add to your Podfile:
|
|
@@ -316,6 +403,8 @@ The library ships a small CLI at `npx react-native-notify-kit`. Currently one co
|
|
|
316
403
|
|
|
317
404
|
- `npx react-native-notify-kit init-nse` — scaffolds an iOS Notification Service Extension (Swift), patches the Podfile, and wires `.pbxproj`. See [docs/fcm-mode.mdx#ios-nse-setup](docs/fcm-mode.mdx#ios-nse-setup) for options.
|
|
318
405
|
|
|
406
|
+
Expo CNG users should use the config plugin for NSE setup instead of the CLI.
|
|
407
|
+
|
|
319
408
|
The CLI is prepacked into the main package at publish time, so `npx react-native-notify-kit` works immediately after `yarn add react-native-notify-kit` — no separate install.
|
|
320
409
|
|
|
321
410
|
## Jest Testing
|
|
@@ -346,6 +435,7 @@ This fork is a complete migration to React Native's **New Architecture**:
|
|
|
346
435
|
- **Minimum React Native 0.73**, development target **0.84**
|
|
347
436
|
- **Toolchain**: Yarn 4, Node 22+, Java 17, compileSdk/targetSdk 35
|
|
348
437
|
- **Single Android module** — the original Notifee shipped a pre-compiled AAR bundled inside the npm tarball under a frozen Maven coordinate; this fork compiles the core from source as part of the React Native bridge module on every consumer build. Eliminates the `FAIL_ON_PROJECT_REPOS` issue on RN 0.74+ and the Gradle cache staleness bug that could serve outdated bytecode after `yarn upgrade`.
|
|
438
|
+
- **Expo CNG development builds** — iOS FCM Mode NSE automation and Android foreground service manifest configuration are available through the config plugin. Android Expo FCM smoke validation uses RNFirebase data-only messages plus `notifee.handleFcmMessage`.
|
|
349
439
|
- **Core notification logic (NotifeeCore) is unchanged** — the public API is fully compatible with the original Notifee
|
|
350
440
|
- **35 upstream bugs fixed** — see [Bugs Fixed from Upstream Notifee](#bugs-fixed-from-upstream-notifee) below
|
|
351
441
|
- **Reliable trigger notifications** — AlarmManager is the default backend instead of WorkManager, with automatic fallback when exact alarm permission is not granted
|
|
@@ -772,8 +862,8 @@ distribution model in 9.2.0 — the core compiles from source as part of the bri
|
|
|
772
862
|
module, so there is no Maven coordinate to resolve, no `extraMavenRepos` to configure
|
|
773
863
|
on Expo, and no `FAIL_ON_PROJECT_REPOS` conflict on RN 0.74+. Migrating from
|
|
774
864
|
`@notifee/react-native` to `react-native-notify-kit` removes the error with no
|
|
775
|
-
additional `build.gradle` patching, no config plugin
|
|
776
|
-
entry.
|
|
865
|
+
additional `build.gradle` patching, no Android config plugin for this Maven issue,
|
|
866
|
+
and no Expo `extraMavenRepos` entry.
|
|
777
867
|
|
|
778
868
|
References: upstream issues [#1079](https://github.com/invertase/notifee/issues/1079),
|
|
779
869
|
[#1226](https://github.com/invertase/notifee/issues/1226),
|
package/app.plugin.js
ADDED
|
@@ -41,6 +41,7 @@ const fs = __importStar(require("fs"));
|
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const xcode_1 = __importDefault(require("xcode"));
|
|
43
43
|
const detectProject_1 = require("../lib/detectProject");
|
|
44
|
+
const initNseCore_1 = require("../lib/initNseCore");
|
|
44
45
|
const writeTemplates_1 = require("../lib/writeTemplates");
|
|
45
46
|
const patchPodfile_1 = require("../lib/patchPodfile");
|
|
46
47
|
const patchXcodeProject_1 = require("../lib/patchXcodeProject");
|
|
@@ -51,15 +52,13 @@ const logger = __importStar(require("../lib/logger"));
|
|
|
51
52
|
*/
|
|
52
53
|
async function initNse(opts) {
|
|
53
54
|
const { targetName = 'NotifyKitNSE', bundleSuffix = '.NotifyKitNSE', force = false, dryRun = false, } = opts;
|
|
54
|
-
// 0. Validate
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
process.exit(1);
|
|
55
|
+
// 0. Validate user-provided names before they reach Podfile/pbxproj patching.
|
|
56
|
+
try {
|
|
57
|
+
(0, initNseCore_1.validateNseTargetName)(targetName);
|
|
58
|
+
(0, initNseCore_1.validateNseBundleSuffix)(bundleSuffix);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
logger.error(`Invalid bundle suffix '${bundleSuffix}'. Must start with '.' and contain only letters, digits, hyphens, and dots.`);
|
|
60
|
+
catch (e) {
|
|
61
|
+
logger.error(e instanceof Error ? e.message : String(e));
|
|
63
62
|
process.exit(1);
|
|
64
63
|
}
|
|
65
64
|
// 1. Detect project
|
|
@@ -74,7 +73,7 @@ async function initNse(opts) {
|
|
|
74
73
|
const absIosDir = path.resolve(projectInfo.iosDir);
|
|
75
74
|
logger.success(`Detected iOS project at ${projectInfo.xcodeProjectPath}`);
|
|
76
75
|
// 2. Derive bundle ID
|
|
77
|
-
const bundleId = (0,
|
|
76
|
+
const bundleId = (0, initNseCore_1.deriveNseBundleIdentifier)(projectInfo.parentBundleId, bundleSuffix, projectInfo.parentTargetName);
|
|
78
77
|
if (projectInfo.parentBundleId?.includes('$(') &&
|
|
79
78
|
(bundleId.includes('$(') || bundleId.includes('${'))) {
|
|
80
79
|
logger.warn(`Parent bundle ID uses a variable: ${projectInfo.parentBundleId}\n` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initNse.js","sourceRoot":"","sources":["../../src/commands/initNse.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"initNse.js","sourceRoot":"","sources":["../../src/commands/initNse.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { deriveNseBundleIdentifier as deriveBundleId } from './initNseCore';
|
|
1
2
|
export interface ProjectInfo {
|
|
2
3
|
xcodeProjectPath: string;
|
|
3
4
|
pbxprojPath: string;
|
|
@@ -9,7 +10,3 @@ export interface ProjectInfo {
|
|
|
9
10
|
* Detects the iOS project directory and parses key metadata.
|
|
10
11
|
*/
|
|
11
12
|
export declare function detectIosProject(iosPath?: string): ProjectInfo;
|
|
12
|
-
/**
|
|
13
|
-
* Derives the NSE bundle ID from the parent target.
|
|
14
|
-
*/
|
|
15
|
-
export declare function deriveBundleId(parentBundleId: string | null, suffix: string, parentTargetName?: string): string;
|
|
@@ -36,11 +36,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.deriveBundleId = void 0;
|
|
39
40
|
exports.detectIosProject = detectIosProject;
|
|
40
|
-
exports.deriveBundleId = deriveBundleId;
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const path = __importStar(require("path"));
|
|
43
43
|
const xcode_1 = __importDefault(require("xcode"));
|
|
44
|
+
var initNseCore_1 = require("./initNseCore");
|
|
45
|
+
Object.defineProperty(exports, "deriveBundleId", { enumerable: true, get: function () { return initNseCore_1.deriveNseBundleIdentifier; } });
|
|
44
46
|
/**
|
|
45
47
|
* Detects the iOS project directory and parses key metadata.
|
|
46
48
|
*/
|
|
@@ -75,37 +77,6 @@ function detectIosProject(iosPath) {
|
|
|
75
77
|
parentTargetName: targetName,
|
|
76
78
|
};
|
|
77
79
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Derives the NSE bundle ID from the parent target.
|
|
80
|
-
*/
|
|
81
|
-
function deriveBundleId(parentBundleId, suffix, parentTargetName) {
|
|
82
|
-
if (!parentBundleId) {
|
|
83
|
-
return `$(PRODUCT_BUNDLE_IDENTIFIER:default)${suffix}`;
|
|
84
|
-
}
|
|
85
|
-
if (!parentBundleId.includes('$(') && !parentBundleId.includes('${')) {
|
|
86
|
-
return parentBundleId + suffix;
|
|
87
|
-
}
|
|
88
|
-
const expandedBundleId = expandKnownBundleIdVariables(parentBundleId, parentTargetName);
|
|
89
|
-
if (expandedBundleId && !expandedBundleId.includes('$(') && !expandedBundleId.includes('${')) {
|
|
90
|
-
return expandedBundleId + suffix;
|
|
91
|
-
}
|
|
92
|
-
// Variable-based bundle ID we could not fully resolve statically.
|
|
93
|
-
return `$(PRODUCT_BUNDLE_IDENTIFIER:default)${suffix}`;
|
|
94
|
-
}
|
|
95
|
-
function expandKnownBundleIdVariables(bundleId, parentTargetName) {
|
|
96
|
-
if (!parentTargetName) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
const normalizedTargetName = toRfc1034Identifier(parentTargetName);
|
|
100
|
-
return bundleId
|
|
101
|
-
.replace(/\$\((?:PRODUCT_NAME|TARGET_NAME):rfc1034identifier\)/g, normalizedTargetName)
|
|
102
|
-
.replace(/\$\{(?:PRODUCT_NAME|TARGET_NAME):rfc1034identifier\}/g, normalizedTargetName)
|
|
103
|
-
.replace(/\$\((?:PRODUCT_NAME|TARGET_NAME)\)/g, parentTargetName)
|
|
104
|
-
.replace(/\$\{(?:PRODUCT_NAME|TARGET_NAME)\}/g, parentTargetName);
|
|
105
|
-
}
|
|
106
|
-
function toRfc1034Identifier(value) {
|
|
107
|
-
return value.replace(/[^A-Za-z0-9.-]/g, '-');
|
|
108
|
-
}
|
|
109
80
|
function readParentTarget(pbxprojPath) {
|
|
110
81
|
const proj = xcode_1.default.project(pbxprojPath);
|
|
111
82
|
proj.parseSync();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detectProject.js","sourceRoot":"","sources":["../../src/lib/detectProject.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"detectProject.js","sourceRoot":"","sources":["../../src/lib/detectProject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function validateNseTargetName(targetName: string): void;
|
|
2
|
+
export declare function validateNseBundleSuffix(bundleSuffix: string): void;
|
|
3
|
+
export declare function deriveNseBundleIdentifier(parentBundleId: string | null, suffix: string, parentTargetName?: string): string;
|
|
4
|
+
export declare function renderNotificationServiceSwift(): string;
|
|
5
|
+
export declare function renderNseInfoPlist(options: {
|
|
6
|
+
targetName: string;
|
|
7
|
+
}): string;
|
|
8
|
+
export declare function renderNseEntitlementsPlist(): string;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateNseTargetName = validateNseTargetName;
|
|
4
|
+
exports.validateNseBundleSuffix = validateNseBundleSuffix;
|
|
5
|
+
exports.deriveNseBundleIdentifier = deriveNseBundleIdentifier;
|
|
6
|
+
exports.renderNotificationServiceSwift = renderNotificationServiceSwift;
|
|
7
|
+
exports.renderNseInfoPlist = renderNseInfoPlist;
|
|
8
|
+
exports.renderNseEntitlementsPlist = renderNseEntitlementsPlist;
|
|
9
|
+
const NSE_TARGET_NAME_PATTERN = /^[A-Za-z0-9_\-.]+$/;
|
|
10
|
+
const NSE_BUNDLE_SUFFIX_PATTERN = /^\.[A-Za-z0-9\-.]+$/;
|
|
11
|
+
const PRODUCT_BUNDLE_IDENTIFIER_PLACEHOLDER = '$(PRODUCT_BUNDLE_IDENTIFIER:default)';
|
|
12
|
+
const NOTIFICATION_SERVICE_SWIFT = String.raw `import Foundation
|
|
13
|
+
import UserNotifications
|
|
14
|
+
import RNNotifeeCore
|
|
15
|
+
|
|
16
|
+
private func nseLog(_ message: String) {
|
|
17
|
+
NSLog("[NotifyKitNSE] %@", message)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private func requestedAttachmentURLs(from userInfo: [AnyHashable: Any]) -> [String] {
|
|
21
|
+
guard let serializedOptions = userInfo["notifee_options"] as? String,
|
|
22
|
+
let data = serializedOptions.data(using: .utf8),
|
|
23
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
24
|
+
let ios = json["ios"] as? [String: Any],
|
|
25
|
+
let attachments = ios["attachments"] as? [[String: Any]] else {
|
|
26
|
+
return []
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return attachments.compactMap { attachment in
|
|
30
|
+
attachment["url"] as? String
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class NotificationService: UNNotificationServiceExtension {
|
|
35
|
+
var contentHandler: ((UNNotificationContent) -> Void)?
|
|
36
|
+
var bestAttemptContent: UNMutableNotificationContent?
|
|
37
|
+
private let deliveryLock = NSLock()
|
|
38
|
+
private var didDeliver = false
|
|
39
|
+
|
|
40
|
+
override func didReceive(
|
|
41
|
+
_ request: UNNotificationRequest,
|
|
42
|
+
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
|
|
43
|
+
) {
|
|
44
|
+
let mutableContent = request.content.mutableCopy() as? UNMutableNotificationContent
|
|
45
|
+
|
|
46
|
+
deliveryLock.lock()
|
|
47
|
+
didDeliver = false
|
|
48
|
+
self.contentHandler = contentHandler
|
|
49
|
+
self.bestAttemptContent = mutableContent
|
|
50
|
+
deliveryLock.unlock()
|
|
51
|
+
|
|
52
|
+
let requestedAttachmentUrls = requestedAttachmentURLs(from: request.content.userInfo)
|
|
53
|
+
|
|
54
|
+
nseLog(
|
|
55
|
+
"didReceive id=\(request.identifier) title=\(request.content.title) " +
|
|
56
|
+
"hasNotifeeOptions=\(request.content.userInfo["notifee_options"] != nil) " +
|
|
57
|
+
"requestedAttachments=\(requestedAttachmentUrls.count) " +
|
|
58
|
+
"urls=\(requestedAttachmentUrls.joined(separator: ","))"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
guard let bestAttemptContent = mutableContent else {
|
|
62
|
+
nseLog("mutableCopy failed for id=\(request.identifier); delivering original content")
|
|
63
|
+
deliverOnce(request.content)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
NotifeeExtensionHelper.populateNotificationContent(
|
|
68
|
+
request,
|
|
69
|
+
with: bestAttemptContent,
|
|
70
|
+
withContentHandler: { [weak self] content in
|
|
71
|
+
let deliveredAttachmentIds = content.attachments.map(\.identifier).joined(separator: ",")
|
|
72
|
+
nseLog(
|
|
73
|
+
"contentHandler id=\(request.identifier) title=\(content.title) " +
|
|
74
|
+
"deliveredAttachments=\(content.attachments.count) " +
|
|
75
|
+
"identifiers=\(deliveredAttachmentIds)"
|
|
76
|
+
)
|
|
77
|
+
self?.deliverOnce(content)
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private func deliverOnce(_ content: UNNotificationContent) {
|
|
83
|
+
var handler: ((UNNotificationContent) -> Void)?
|
|
84
|
+
|
|
85
|
+
deliveryLock.lock()
|
|
86
|
+
if !didDeliver {
|
|
87
|
+
didDeliver = true
|
|
88
|
+
handler = contentHandler
|
|
89
|
+
contentHandler = nil
|
|
90
|
+
bestAttemptContent = nil
|
|
91
|
+
}
|
|
92
|
+
deliveryLock.unlock()
|
|
93
|
+
|
|
94
|
+
handler?(content)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
override func serviceExtensionTimeWillExpire() {
|
|
98
|
+
deliveryLock.lock()
|
|
99
|
+
let content = bestAttemptContent
|
|
100
|
+
deliveryLock.unlock()
|
|
101
|
+
|
|
102
|
+
if let bestAttemptContent = content {
|
|
103
|
+
nseLog(
|
|
104
|
+
"serviceExtensionTimeWillExpire id=\(bestAttemptContent.userInfo["gcm.message_id"] ?? "n/a") " +
|
|
105
|
+
"title=\(bestAttemptContent.title) " +
|
|
106
|
+
"deliveredAttachments=\(bestAttemptContent.attachments.count)"
|
|
107
|
+
)
|
|
108
|
+
deliverOnce(bestAttemptContent)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
const NSE_INFO_PLIST_TEMPLATE = `<?xml version="1.0" encoding="UTF-8"?>
|
|
114
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
115
|
+
<plist version="1.0">
|
|
116
|
+
<dict>
|
|
117
|
+
\t<key>CFBundleDisplayName</key>
|
|
118
|
+
\t<string>{{TARGET_NAME}}</string>
|
|
119
|
+
\t<key>CFBundleExecutable</key>
|
|
120
|
+
\t<string>$(EXECUTABLE_NAME)</string>
|
|
121
|
+
\t<key>CFBundleIdentifier</key>
|
|
122
|
+
\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
123
|
+
\t<key>CFBundleInfoDictionaryVersion</key>
|
|
124
|
+
\t<string>6.0</string>
|
|
125
|
+
\t<key>CFBundleName</key>
|
|
126
|
+
\t<string>$(PRODUCT_NAME)</string>
|
|
127
|
+
\t<key>CFBundlePackageType</key>
|
|
128
|
+
\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
|
129
|
+
\t<key>CFBundleShortVersionString</key>
|
|
130
|
+
\t<string>1.0</string>
|
|
131
|
+
\t<key>CFBundleVersion</key>
|
|
132
|
+
\t<string>1</string>
|
|
133
|
+
\t<key>NSExtension</key>
|
|
134
|
+
\t<dict>
|
|
135
|
+
\t\t<key>NSExtensionPointIdentifier</key>
|
|
136
|
+
\t\t<string>com.apple.usernotifications.service</string>
|
|
137
|
+
\t\t<key>NSExtensionPrincipalClass</key>
|
|
138
|
+
\t\t<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
|
|
139
|
+
\t</dict>
|
|
140
|
+
</dict>
|
|
141
|
+
</plist>
|
|
142
|
+
`;
|
|
143
|
+
const NSE_ENTITLEMENTS_PLIST = `<?xml version="1.0" encoding="UTF-8"?>
|
|
144
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
145
|
+
<plist version="1.0">
|
|
146
|
+
<dict>
|
|
147
|
+
</dict>
|
|
148
|
+
</plist>
|
|
149
|
+
`;
|
|
150
|
+
function validateNseTargetName(targetName) {
|
|
151
|
+
if (!NSE_TARGET_NAME_PATTERN.test(targetName)) {
|
|
152
|
+
throw new Error(`Invalid target name '${targetName}'. Must match [A-Za-z0-9_-.]\n` +
|
|
153
|
+
' Target names can only contain letters, digits, underscores, hyphens, and dots.');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function validateNseBundleSuffix(bundleSuffix) {
|
|
157
|
+
if (!NSE_BUNDLE_SUFFIX_PATTERN.test(bundleSuffix)) {
|
|
158
|
+
throw new Error(`Invalid bundle suffix '${bundleSuffix}'. Must start with '.' and contain only letters, digits, hyphens, and dots.`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function deriveNseBundleIdentifier(parentBundleId, suffix, parentTargetName) {
|
|
162
|
+
if (!parentBundleId) {
|
|
163
|
+
return `${PRODUCT_BUNDLE_IDENTIFIER_PLACEHOLDER}${suffix}`;
|
|
164
|
+
}
|
|
165
|
+
if (!parentBundleId.includes('$(') && !parentBundleId.includes('${')) {
|
|
166
|
+
return parentBundleId + suffix;
|
|
167
|
+
}
|
|
168
|
+
const expandedBundleId = expandKnownBundleIdVariables(parentBundleId, parentTargetName);
|
|
169
|
+
if (expandedBundleId && !expandedBundleId.includes('$(') && !expandedBundleId.includes('${')) {
|
|
170
|
+
return expandedBundleId + suffix;
|
|
171
|
+
}
|
|
172
|
+
return `${PRODUCT_BUNDLE_IDENTIFIER_PLACEHOLDER}${suffix}`;
|
|
173
|
+
}
|
|
174
|
+
function renderNotificationServiceSwift() {
|
|
175
|
+
return NOTIFICATION_SERVICE_SWIFT;
|
|
176
|
+
}
|
|
177
|
+
function renderNseInfoPlist(options) {
|
|
178
|
+
return NSE_INFO_PLIST_TEMPLATE.replace(/\{\{TARGET_NAME\}\}/g, options.targetName);
|
|
179
|
+
}
|
|
180
|
+
function renderNseEntitlementsPlist() {
|
|
181
|
+
return NSE_ENTITLEMENTS_PLIST;
|
|
182
|
+
}
|
|
183
|
+
function expandKnownBundleIdVariables(bundleId, parentTargetName) {
|
|
184
|
+
if (!parentTargetName) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const normalizedTargetName = toRfc1034Identifier(parentTargetName);
|
|
188
|
+
return bundleId
|
|
189
|
+
.replace(/\$\((?:PRODUCT_NAME|TARGET_NAME):rfc1034identifier\)/g, normalizedTargetName)
|
|
190
|
+
.replace(/\$\{(?:PRODUCT_NAME|TARGET_NAME):rfc1034identifier\}/g, normalizedTargetName)
|
|
191
|
+
.replace(/\$\((?:PRODUCT_NAME|TARGET_NAME)\)/g, parentTargetName)
|
|
192
|
+
.replace(/\$\{(?:PRODUCT_NAME|TARGET_NAME)\}/g, parentTargetName);
|
|
193
|
+
}
|
|
194
|
+
function toRfc1034Identifier(value) {
|
|
195
|
+
return value.replace(/[^A-Za-z0-9.-]/g, '-');
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=initNseCore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initNseCore.js","sourceRoot":"","sources":["../../src/lib/initNseCore.ts"],"names":[],"mappings":";;AAkJA,sDAOC;AAED,0DAMC;AAED,8DAmBC;AAED,wEAEC;AAED,gDAEC;AAED,gEAEC;AAlMD,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AACrD,MAAM,yBAAyB,GAAG,qBAAqB,CAAC;AAExD,MAAM,qCAAqC,GAAG,sCAAsC,CAAC;AAErF,MAAM,0BAA0B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoG5C,CAAC;AAEF,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B/B,CAAC;AAEF,MAAM,sBAAsB,GAAG;;;;;;CAM9B,CAAC;AAEF,SAAgB,qBAAqB,CAAC,UAAkB;IACtD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,wBAAwB,UAAU,gCAAgC;YAChE,kFAAkF,CACrF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,uBAAuB,CAAC,YAAoB;IAC1D,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,0BAA0B,YAAY,6EAA6E,CACpH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,yBAAyB,CACvC,cAA6B,EAC7B,MAAc,EACd,gBAAyB;IAEzB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,GAAG,qCAAqC,GAAG,MAAM,EAAE,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,OAAO,cAAc,GAAG,MAAM,CAAC;IACjC,CAAC;IAED,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACxF,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7F,OAAO,gBAAgB,GAAG,MAAM,CAAC;IACnC,CAAC;IAED,OAAO,GAAG,qCAAqC,GAAG,MAAM,EAAE,CAAC;AAC7D,CAAC;AAED,SAAgB,8BAA8B;IAC5C,OAAO,0BAA0B,CAAC;AACpC,CAAC;AAED,SAAgB,kBAAkB,CAAC,OAA+B;IAChE,OAAO,uBAAuB,CAAC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;AACrF,CAAC;AAED,SAAgB,0BAA0B;IACxC,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED,SAAS,4BAA4B,CAAC,QAAgB,EAAE,gBAAyB;IAC/E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAEnE,OAAO,QAAQ;SACZ,OAAO,CAAC,uDAAuD,EAAE,oBAAoB,CAAC;SACtF,OAAO,CAAC,uDAAuD,EAAE,oBAAoB,CAAC;SACtF,OAAO,CAAC,qCAAqC,EAAE,gBAAgB,CAAC;SAChE,OAAO,CAAC,qCAAqC,EAAE,gBAAgB,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export interface NotifyKitNsePodfilePatchOptions {
|
|
2
|
+
targetName: string;
|
|
3
|
+
packagePathFromIos?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface NotifyKitNsePodfilePatchResult {
|
|
6
|
+
contents: string;
|
|
7
|
+
didChange: boolean;
|
|
8
|
+
}
|
|
1
9
|
/**
|
|
2
10
|
* Patches the Podfile to add the NSE target with RNNotifeeCore pod.
|
|
3
11
|
* The NSE target is nested inside the main app target so CocoaPods can
|
|
@@ -7,6 +15,7 @@
|
|
|
7
15
|
* Idempotent: returns false when no Podfile changes are needed.
|
|
8
16
|
*/
|
|
9
17
|
export declare function patchPodfile(podfilePath: string, targetName: string, dryRun: boolean): boolean;
|
|
18
|
+
export declare function patchPodfileForNotifyKitNse(podfileText: string, options: NotifyKitNsePodfilePatchOptions): NotifyKitNsePodfilePatchResult;
|
|
10
19
|
/**
|
|
11
20
|
* Returns the patched Podfile content without writing to disk (for dry-run
|
|
12
21
|
* preview or testing).
|