cordova-plugin-reteno 2.2.0 → 2.2.2
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 +2 -4
- package/docs/Cordova/Action Buttons/README.md +62 -0
- package/docs/Cordova/AppInbox/README.md +55 -0
- package/docs/Cordova/AppLifeCycleEvents/README.md +80 -0
- package/docs/Cordova/Ecommerce/README.md +144 -0
- package/docs/Cordova/InAppMessages/README.md +72 -0
- package/docs/Cordova/Push notification/README.md +129 -0
- package/docs/Cordova/Recommendations/README.md +62 -0
- package/docs/Cordova/SetupGuide/Android.md +135 -0
- package/docs/Cordova/SetupGuide/IOS.md +325 -0
- package/docs/Cordova/SetupGuide/README.md +91 -0
- package/docs/Cordova/Tracking user behaviour/README.md +52 -0
- package/docs/Cordova/Tracking user information/README.md +112 -0
- package/docs/Ionic/Action Buttons/README.md +66 -0
- package/docs/Ionic/AppInbox/README.md +61 -0
- package/docs/Ionic/AppLifeCycleEvents/README.md +77 -0
- package/docs/Ionic/Ecommerce/README.md +139 -0
- package/docs/Ionic/InAppMessages/README.md +65 -0
- package/docs/Ionic/Push notification/README.md +133 -0
- package/docs/Ionic/Recommendations/README.md +46 -0
- package/docs/Ionic/SetupGuide/Android.md +173 -0
- package/docs/Ionic/SetupGuide/IOS.md +354 -0
- package/docs/Ionic/SetupGuide/README.md +167 -0
- package/docs/Ionic/Tracking user behaviour/README.md +31 -0
- package/docs/Ionic/Tracking user information/README.md +98 -0
- package/package.json +1 -1
- package/plugin.xml +20 -2
- package/scripts/ios-podfile-use-modular-headers.js +109 -0
- package/scripts/validate-install.js +37 -9
- package/src/android/app/build.gradle +1 -1
- package/src/android/app/src/main/java/com/reteno/plugin/RetenoPlugin.java +29 -9
- package/src/android/reteno.gradle +19 -9
- package/src/ios/RetenoPlugin.swift +37 -5
- package/src/ios/RetenoPluginBootstrap.m +117 -0
- package/types/index.ts +1 -1
- package/docs/android.md +0 -264
- package/docs/api.md +0 -734
- package/docs/ios.md +0 -495
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Android
|
|
2
|
+
|
|
3
|
+
### Getting started with Reteno for Ionic (Cordova)
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
> Requirement: `cordova-android >= 12.0.0`.
|
|
8
|
+
|
|
9
|
+
1. Install plugin:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
ionic cordova plugin add cordova-plugin-reteno --variable RETENO_ACCESS_KEY=YOUR_KEY
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
2. Install Ionic wrapper from npmjs:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Choose the wrapper major that matches your `@awesome-cordova-plugins/core` (v5–v9). API is identical across versions — see the compatibility matrix in [Setup overview](./README.md#2-install-wrapper-awesome-cordova-plugins-reteno).
|
|
22
|
+
|
|
23
|
+
3. Add Android platform if needed:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
ionic cordova platform add android
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configure via `config.xml`
|
|
30
|
+
|
|
31
|
+
```xml
|
|
32
|
+
<widget ...>
|
|
33
|
+
<plugin name="cordova-plugin-reteno" spec="cordova-plugin-reteno">
|
|
34
|
+
<variable name="RETENO_ACCESS_KEY" value="YOUR_KEY" />
|
|
35
|
+
</plugin>
|
|
36
|
+
</widget>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Notes:
|
|
40
|
+
|
|
41
|
+
- Access-key precedence: `RETENO_ACCESS_KEY` → deprecated `SDK_ACCESS_KEY` → AndroidManifest meta-data injected by the plugin. New integrations should use `RETENO_ACCESS_KEY`.
|
|
42
|
+
- If you changed plugin variables, usually you need reinstall/re-add:
|
|
43
|
+
- `ionic cordova plugin rm cordova-plugin-reteno && ionic cordova plugin add ...`
|
|
44
|
+
- or `ionic cordova platform rm android && ionic cordova platform add android`
|
|
45
|
+
|
|
46
|
+
## Request notification permission (Android 13+)
|
|
47
|
+
|
|
48
|
+
Android 13+ (`targetSdkVersion >= 33`) requires runtime permission for notifications. The plugin injects `POST_NOTIFICATIONS` into the manifest, but you still must request it at runtime:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const granted = await this.reteno.requestNotificationPermission();
|
|
52
|
+
// granted: 1 — granted, 0 — declined
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Initialize SDK
|
|
56
|
+
|
|
57
|
+
Use `Platform.ready()` and call `this.reteno.init(...)` once. Full example is in [Setup overview](./README.md#initialize-the-sdk).
|
|
58
|
+
|
|
59
|
+
## Firebase Cloud Messaging
|
|
60
|
+
|
|
61
|
+
- Download `google-services.json` from Firebase Console.
|
|
62
|
+
- Place it in project root or `resources/android/`.
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
|
|
66
|
+

|
|
67
|
+
|
|
68
|
+

|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
Official references:
|
|
73
|
+
|
|
74
|
+
- [Set up Firebase for FCM](https://docs.reteno.com/reference/setting-up-your-firebase-application-for-firebase-cloud-messaging)
|
|
75
|
+
- [Connect app in Reteno](https://docs.reteno.com/docs/connect-your-mobile-app)
|
|
76
|
+
|
|
77
|
+
## Without Firebasex
|
|
78
|
+
|
|
79
|
+
If you do not need `cordova-plugin-firebasex` features, Reteno push still works on Android. For FCM to work, your Cordova Android project must have:
|
|
80
|
+
|
|
81
|
+
1. `google-services.json` from Firebase Console.
|
|
82
|
+
2. Google Services Gradle plugin (`com.google.gms.google-services`) applied.
|
|
83
|
+
|
|
84
|
+
How to verify:
|
|
85
|
+
|
|
86
|
+
- `platforms/android/app/google-services.json` exists.
|
|
87
|
+
- `platforms/android/app/build.gradle` contains `com.google.gms.google-services`.
|
|
88
|
+
- Build logs do not contain `google-services.json not found`.
|
|
89
|
+
|
|
90
|
+
## Warning: Reteno + Firebasex
|
|
91
|
+
|
|
92
|
+
If Firebasex registers its own `FirebaseMessagingService`, Reteno may not receive FCM callbacks.
|
|
93
|
+
|
|
94
|
+
## Custom FCM service (optional)
|
|
95
|
+
|
|
96
|
+
Only if you need custom native handling: extend `RetenoFirebaseMessagingService` and call `super` methods.
|
|
97
|
+
|
|
98
|
+
## Capacitor setup (Android)
|
|
99
|
+
|
|
100
|
+
Capacitor uses Cordova plugins through a compatibility layer, but does not execute Cordova plugin hooks. Some automatic steps from Cordova must be done manually.
|
|
101
|
+
|
|
102
|
+
### 1. Install plugin and sync
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
npm install cordova-plugin-reteno
|
|
106
|
+
npx cap sync android
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Install the Ionic wrapper from npm:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 2. Configure `RETENO_ACCESS_KEY` in `capacitor.config.ts`
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { CapacitorConfig } from '@capacitor/cli';
|
|
119
|
+
|
|
120
|
+
const config: CapacitorConfig = {
|
|
121
|
+
// ...
|
|
122
|
+
cordova: {
|
|
123
|
+
preferences: {
|
|
124
|
+
RETENO_ACCESS_KEY: 'YOUR_KEY',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default config;
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The plugin's `reteno.gradle` script automatically reads this value from `capacitor.config.json` (generated by Capacitor CLI from `capacitor.config.ts`) and patches the Android manifest at build time. No manual manifest editing is required.
|
|
133
|
+
|
|
134
|
+
Then run:
|
|
135
|
+
|
|
136
|
+
```sh
|
|
137
|
+
npx cap sync android
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
You can also pass key explicitly in JS:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
await this.reteno.init({ accessKey: 'YOUR_KEY' });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 3. Add `google-services.json` manually
|
|
147
|
+
|
|
148
|
+
Cordova hook that auto-copies `google-services.json` does not run in Capacitor.
|
|
149
|
+
|
|
150
|
+
1. Download `google-services.json` from Firebase Console.
|
|
151
|
+
2. Copy it to `android/app/google-services.json`.
|
|
152
|
+
3. Run `npx cap sync android`.
|
|
153
|
+
|
|
154
|
+
### 4. Verify Google Services Gradle plugin
|
|
155
|
+
|
|
156
|
+
Check `android/app/build.gradle` contains:
|
|
157
|
+
|
|
158
|
+
```gradle
|
|
159
|
+
apply plugin: 'com.google.gms.google-services'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
If not, add it manually or install `@capacitor-firebase/messaging` (or similar).
|
|
163
|
+
|
|
164
|
+
### 5. Initialize and request permission
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
await this.reteno.init();
|
|
168
|
+
const granted = await this.reteno.requestNotificationPermission();
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Deeplinks in push payloads
|
|
172
|
+
|
|
173
|
+
Reteno can deliver deeplinks, but routing inside Ionic app should be handled by app-level deeplink layer (scheme/App Links/provider).
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Ionic iOS SDK Setup
|
|
2
|
+
|
|
3
|
+
Official guide: https://docs.reteno.com/reference/ios
|
|
4
|
+
|
|
5
|
+
## Minimum SDK Requirements
|
|
6
|
+
|
|
7
|
+
- iOS 15.0+
|
|
8
|
+
- Xcode 15.0+
|
|
9
|
+
- Swift 5.7+
|
|
10
|
+
|
|
11
|
+
## Install plugin and wrapper
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
ionic cordova plugin add cordova-plugin-reteno --variable RETENO_ACCESS_KEY=YOUR_KEY
|
|
15
|
+
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For Ionic projects that use an older `@awesome-cordova-plugins/core` major (v5/v6/v7/v8), install the matching wrapper major — see the compatibility matrix in [Setup overview](./README.md#2-install-wrapper-awesome-cordova-plugins-reteno).
|
|
19
|
+
|
|
20
|
+
In `config.xml` add:
|
|
21
|
+
|
|
22
|
+
```xml
|
|
23
|
+
<preference name="deployment-target" value="15.0" />
|
|
24
|
+
<preference name="RETENO_ACCESS_KEY" value="YOUR_RETENO_ACCESS_KEY" />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`RETENO_ACCESS_KEY` is the preferred name. The deprecated `SDK_ACCESS_KEY` preference remains supported for backward compatibility.
|
|
28
|
+
|
|
29
|
+
## Add Notification Service Extension (NSE)
|
|
30
|
+
|
|
31
|
+
1. `File > New > Target...` -> `Notification Service Extension`
|
|
32
|
+
2. Name: `NotificationServiceExtension`
|
|
33
|
+
3. Do not activate scheme.
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/create_notification_service_extension.png" width="50%"/>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/choose_options_for_extension.png" width="50%"/>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
4. Ensure extension deployment target equals main app target.
|
|
44
|
+
|
|
45
|
+
<p align="center">
|
|
46
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/configure_target.png" width="50%"/>
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
5. Replace `NotificationService.swift`:
|
|
50
|
+
|
|
51
|
+
```swift
|
|
52
|
+
import UserNotifications
|
|
53
|
+
import Reteno
|
|
54
|
+
|
|
55
|
+
class NotificationService: RetenoNotificationServiceExtension {}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Add App Groups
|
|
59
|
+
|
|
60
|
+
Enable App Groups in main target and `NotificationServiceExtension`.
|
|
61
|
+
Group format:
|
|
62
|
+
|
|
63
|
+
`group.{bundle_id}.reteno-local-storage`
|
|
64
|
+
|
|
65
|
+
<p align="center">
|
|
66
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/add_group_main_target.png" width="50%"/>
|
|
67
|
+
</p>
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/app_groups_capability.png" width="50%"/>
|
|
71
|
+
</p>
|
|
72
|
+
|
|
73
|
+
<p align="center">
|
|
74
|
+
<img src="https://raw.githubusercontent.com/reteno-com/reteno-mobile-documentation/main/Ionic/SetupGuide/Resources/add_group_in_extension.png" width="50%"/>
|
|
75
|
+
</p>
|
|
76
|
+
|
|
77
|
+
## Podfile for extension targets
|
|
78
|
+
|
|
79
|
+
Main target pod is injected by plugin automatically.
|
|
80
|
+
For extension targets add in `platforms/ios/Podfile`:
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
target 'App' do
|
|
84
|
+
target 'NotificationServiceExtension' do
|
|
85
|
+
inherit! :search_paths
|
|
86
|
+
pod 'Reteno', '2.7.6'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
target 'NotificationContentExtension' do
|
|
90
|
+
inherit! :search_paths
|
|
91
|
+
pod 'Reteno', '2.7.6'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Optional: Notification Content Extension (Images Carousel)
|
|
97
|
+
|
|
98
|
+
Required for rich push with an **Images Carousel**. Provides the `UNNotificationContentExtension` entry point that renders the custom carousel UI.
|
|
99
|
+
|
|
100
|
+
Official guide: https://docs.reteno.com/reference/ios-images-carousel
|
|
101
|
+
|
|
102
|
+
### Create the extension target
|
|
103
|
+
|
|
104
|
+
In Xcode: **File → New → Target → Notification Content Extension**. Name it `NotificationContentExtension`.
|
|
105
|
+
|
|
106
|
+
### Replace extension files
|
|
107
|
+
|
|
108
|
+
1. **Delete** the generated `MainInterface.storyboard` — it is not used with `RetenoCarouselNotificationViewController`.
|
|
109
|
+
2. Replace `NotificationViewController.swift`:
|
|
110
|
+
|
|
111
|
+
```swift
|
|
112
|
+
import Reteno
|
|
113
|
+
|
|
114
|
+
final class NotificationViewController: RetenoCarouselNotificationViewController {}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Update `Info.plist` of the NCE
|
|
118
|
+
|
|
119
|
+
Open `NotificationContentExtension/Info.plist` as source code and replace the `NSExtension` dict with:
|
|
120
|
+
|
|
121
|
+
```xml
|
|
122
|
+
<key>NSExtension</key>
|
|
123
|
+
<dict>
|
|
124
|
+
<key>NSExtensionAttributes</key>
|
|
125
|
+
<dict>
|
|
126
|
+
<key>UNNotificationExtensionCategory</key>
|
|
127
|
+
<string>ImageCarousel</string>
|
|
128
|
+
<key>UNNotificationExtensionInitialContentSizeRatio</key>
|
|
129
|
+
<real>0.5</real>
|
|
130
|
+
<key>UNNotificationExtensionUserInteractionEnabled</key>
|
|
131
|
+
<true/>
|
|
132
|
+
</dict>
|
|
133
|
+
<key>NSExtensionPointIdentifier</key>
|
|
134
|
+
<string>com.apple.usernotifications.content-extension</string>
|
|
135
|
+
<key>NSExtensionPrincipalClass</key>
|
|
136
|
+
<string>$(PRODUCT_MODULE_NAME).NotificationViewController</string>
|
|
137
|
+
</dict>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Deployment target
|
|
141
|
+
|
|
142
|
+
Make sure the NCE **Deployment Target** in Xcode matches the main app target (iOS 15.0+). A mismatch is the most common reason carousel images fail to display.
|
|
143
|
+
|
|
144
|
+
### Embed App Extensions — Copy only when installing
|
|
145
|
+
|
|
146
|
+
> **This step must be done manually in Xcode.**
|
|
147
|
+
|
|
148
|
+
In Xcode: **Main target → Build Phases → Embed App Extensions**. For **both** `NotificationServiceExtension` and `NotificationContentExtension` ensure **"Copy only when installing"** is **unchecked**.
|
|
149
|
+
|
|
150
|
+
If this checkbox is left on, the extensions will not be embedded during Debug builds and carousel images will not appear.
|
|
151
|
+
|
|
152
|
+
## Capacitor setup (iOS)
|
|
153
|
+
|
|
154
|
+
Capacitor uses Cordova plugins through a compatibility layer, but does not execute Cordova plugin hooks. Some automatic Cordova steps must be done manually.
|
|
155
|
+
|
|
156
|
+
### 1. Install plugin and sync
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
npm install cordova-plugin-reteno
|
|
160
|
+
npx cap sync ios
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Install the Ionic wrapper from npm:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 2. Configure preferences and notification handling in `capacitor.config.ts`
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { CapacitorConfig } from '@capacitor/cli';
|
|
173
|
+
|
|
174
|
+
const config: CapacitorConfig = {
|
|
175
|
+
// ...
|
|
176
|
+
ios: {
|
|
177
|
+
// Reteno must remain UNUserNotificationCenter.delegate to capture the push
|
|
178
|
+
// response that cold-launched the app.
|
|
179
|
+
handleApplicationNotifications: false,
|
|
180
|
+
},
|
|
181
|
+
cordova: {
|
|
182
|
+
preferences: {
|
|
183
|
+
RETENO_ACCESS_KEY: 'YOUR_RETENO_ACCESS_KEY',
|
|
184
|
+
IOS_DEVICE_TOKEN_HANDLING_MODE: 'manual', // default
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export default config;
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Run:
|
|
193
|
+
|
|
194
|
+
```sh
|
|
195
|
+
npx cap sync ios
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Capacitor installs its own `UNUserNotificationCenter` delegate by default. The `handleApplicationNotifications: false` setting prevents that router from replacing Reteno, allowing Reteno to capture a cold-start push response and replay its linked in-app after JavaScript initialization.
|
|
199
|
+
|
|
200
|
+
> This setting is required for push-linked in-app messages on a cold start. If the app uses Capacitor push or local-notification plugins, their notification callbacks must instead be forwarded explicitly because Capacitor's notification router is disabled.
|
|
201
|
+
|
|
202
|
+
### 3. Podfile path and extension pods
|
|
203
|
+
|
|
204
|
+
In Capacitor projects Podfile is `ios/App/Podfile` (not `platforms/ios/Podfile`).
|
|
205
|
+
|
|
206
|
+
For extension targets (`NotificationServiceExtension`, `NotificationContentExtension`), add pods manually inside main target block:
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
target 'App' do
|
|
210
|
+
# ... existing pods ...
|
|
211
|
+
|
|
212
|
+
target 'NotificationServiceExtension' do
|
|
213
|
+
inherit! :search_paths
|
|
214
|
+
pod 'Reteno', '2.7.6'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
target 'NotificationContentExtension' do
|
|
218
|
+
inherit! :search_paths
|
|
219
|
+
pod 'Reteno', '2.7.6'
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Then run:
|
|
225
|
+
|
|
226
|
+
```sh
|
|
227
|
+
cd ios/App && pod install
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 4. Xcode setup
|
|
231
|
+
|
|
232
|
+
Open `ios/App/App.xcworkspace` and complete the same iOS setup steps:
|
|
233
|
+
|
|
234
|
+
- Add NSE target.
|
|
235
|
+
- Add NCE target (if using carousel).
|
|
236
|
+
- Enable App Groups for app + extensions.
|
|
237
|
+
- Uncheck `Copy only when installing` for app extensions.
|
|
238
|
+
|
|
239
|
+
### 5. Firebase setup (if using FCM)
|
|
240
|
+
|
|
241
|
+
1. Add `GoogleService-Info.plist` to the main app target in Xcode.
|
|
242
|
+
2. Add `pod 'FirebaseMessaging'` to `ios/App/Podfile` in main target.
|
|
243
|
+
3. Run `cd ios/App && pod install`.
|
|
244
|
+
|
|
245
|
+
No AppDelegate changes are required for standard flow.
|
|
246
|
+
|
|
247
|
+
### 6. Initialize and request permission
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
await this.reteno.init();
|
|
251
|
+
await this.reteno.requestNotificationPermission();
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Initialize SDK
|
|
255
|
+
|
|
256
|
+
Call `this.reteno.init(...)` after `Platform.ready()`. See [Setup overview](./README.md#initialize-the-sdk).
|
|
257
|
+
|
|
258
|
+
## Request Notification Permission
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
await this.reteno.requestNotificationPermission();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Provide Device Token
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
await this.reteno.setDeviceToken(token);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Using FCM (Firebase Cloud Messaging) on iOS
|
|
271
|
+
|
|
272
|
+
### 1. `FirebaseMessaging` pod
|
|
273
|
+
|
|
274
|
+
Cordova flow: plugin includes `FirebaseMessaging` pod automatically via `plugin.xml`.
|
|
275
|
+
Capacitor flow: verify `pod 'FirebaseMessaging'` exists in `ios/App/Podfile`; if missing, add it manually.
|
|
276
|
+
|
|
277
|
+
### 2. Add `GoogleService-Info.plist`
|
|
278
|
+
|
|
279
|
+
Download `GoogleService-Info.plist` from the [Firebase Console](https://console.firebase.google.com/) and add it to your **iOS app target** in Xcode:
|
|
280
|
+
|
|
281
|
+
- Cordova: open `platforms/ios/<AppName>.xcworkspace`.
|
|
282
|
+
- Capacitor: open `ios/App/App.xcworkspace`.
|
|
283
|
+
- Drag `GoogleService-Info.plist` into the project navigator under the main app target.
|
|
284
|
+
- Make sure **"Copy items if needed"** is checked and the file is added to the **main app target** (not only extension targets).
|
|
285
|
+
|
|
286
|
+
If your app calls `FirebaseApp.configure()` without this file, Firebase will crash at runtime. The plugin avoids auto-configuring Firebase when the file is missing and logs a warning in manual mode.
|
|
287
|
+
|
|
288
|
+
### 3. Configure AppDelegate
|
|
289
|
+
|
|
290
|
+
Nothing to do. Firebase iOS SDK uses **method swizzling** by default — it automatically intercepts `didRegisterForRemoteNotificationsWithDeviceToken` and forwards the APNS token to Firebase without any AppDelegate code.
|
|
291
|
+
|
|
292
|
+
### 4. `IOS_DEVICE_TOKEN_HANDLING_MODE` defaults to `manual`
|
|
293
|
+
|
|
294
|
+
`IOS_DEVICE_TOKEN_HANDLING_MODE` defaults to `manual`, so no extra config is required for the Firebase flow in most cases.
|
|
295
|
+
|
|
296
|
+
If you previously overrode it to `automatic`, switch it back to `manual` to use FCM token forwarding.
|
|
297
|
+
Only set `automatic` when you intentionally want APNS-only token handling by the native Reteno SDK.
|
|
298
|
+
|
|
299
|
+
Supported modes:
|
|
300
|
+
|
|
301
|
+
- `manual` (default)
|
|
302
|
+
- `automatic`
|
|
303
|
+
|
|
304
|
+
Any value other than `automatic` is treated as `manual`.
|
|
305
|
+
Mode is read during `init()` and cannot be changed at runtime from JS.
|
|
306
|
+
|
|
307
|
+
Change mode in `config.xml`:
|
|
308
|
+
|
|
309
|
+
```xml
|
|
310
|
+
<preference name="IOS_DEVICE_TOKEN_HANDLING_MODE" value="automatic" />
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
After changes run `ionic cordova prepare ios` and rebuild.
|
|
314
|
+
|
|
315
|
+
For Capacitor apps, set this value in `capacitor.config.ts` under `cordova.preferences` and run `npx cap sync ios`.
|
|
316
|
+
|
|
317
|
+
When `IOS_DEVICE_TOKEN_HANDLING_MODE` is `manual` **and** Firebase is configured (either already configured by the app or auto-configured because `GoogleService-Info.plist` is present), the plugin automatically:
|
|
318
|
+
|
|
319
|
+
1. Subscribes to Firebase Messaging delegate token updates — every future FCM token rotation is forwarded to Reteno immediately.
|
|
320
|
+
2. Tries to forward the already-cached FCM token on warm starts.
|
|
321
|
+
|
|
322
|
+
## In-app status/pause
|
|
323
|
+
|
|
324
|
+
Usage examples are documented in:
|
|
325
|
+
|
|
326
|
+
- [InAppMessages/README.md](../InAppMessages/README.md)
|
|
327
|
+
|
|
328
|
+
## Screen tracking note
|
|
329
|
+
|
|
330
|
+
In Ionic/Cordova apps use manual tracking:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
await this.reteno.logScreenView('ScreenName');
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Automatic native screen tracking is usually not meaningful in WebView-based apps.
|
|
337
|
+
|
|
338
|
+
## Custom Notification Behavior (iOS)
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
await this.reteno.setWillPresentNotificationOptions({
|
|
342
|
+
options: ['badge', 'sound', 'banner'],
|
|
343
|
+
emitEvent: true,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
await this.reteno.setDidReceiveNotificationResponseHandler({
|
|
347
|
+
enabled: true,
|
|
348
|
+
emitEvent: true,
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Deeplinks in push payloads
|
|
353
|
+
|
|
354
|
+
For hybrid routing use your app deeplink layer (custom scheme / Universal Links / provider).
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Ionic SDK Setup
|
|
2
|
+
|
|
3
|
+
### Reteno for Ionic (Cordova)
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`Reteno` for Ionic uses the `cordova-plugin-reteno` plugin with the Ionic Native wrapper package `awesome-cordova-plugins-reteno`.
|
|
8
|
+
|
|
9
|
+
##### Supported stack
|
|
10
|
+
|
|
11
|
+
- Ionic app with Cordova runtime
|
|
12
|
+
- iOS 15.0+
|
|
13
|
+
- Android with `cordova-android >= 12.0.0`
|
|
14
|
+
|
|
15
|
+
`cordova-plugin-reteno@2.2.2` includes Reteno Android SDK 2.10.2 and Reteno iOS SDK 2.7.6.
|
|
16
|
+
|
|
17
|
+
## Install plugin and wrapper
|
|
18
|
+
|
|
19
|
+
### 1. Install Cordova plugin
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
ionic cordova plugin add cordova-plugin-reteno --variable RETENO_ACCESS_KEY=YOUR_KEY
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. Install wrapper (`awesome-cordova-plugins-reteno`)
|
|
26
|
+
|
|
27
|
+
Pick the wrapper major version that matches your installed `@awesome-cordova-plugins/core`
|
|
28
|
+
(the core package tracks Ionic ecosystem majors). The core runtime API is consistent across
|
|
29
|
+
v5–v9. Newer wrapper releases may add TypeScript declarations for fields supported by the
|
|
30
|
+
Cordova plugin. For example, `awesome-cordova-plugins-reteno@9.2.0` adds the `marketId`
|
|
31
|
+
declaration.
|
|
32
|
+
|
|
33
|
+
| Wrapper version | `@awesome-cordova-plugins/core` | Install |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `awesome-cordova-plugins-reteno@5` | `^5.45.0` | `npm install awesome-cordova-plugins-reteno@5 @awesome-cordova-plugins/core@5` |
|
|
36
|
+
| `awesome-cordova-plugins-reteno@6` | `^6.16.0` | `npm install awesome-cordova-plugins-reteno@6 @awesome-cordova-plugins/core@6` |
|
|
37
|
+
| `awesome-cordova-plugins-reteno@7` | `^7.0.1` | `npm install awesome-cordova-plugins-reteno@7 @awesome-cordova-plugins/core@7` |
|
|
38
|
+
| `awesome-cordova-plugins-reteno@8` | `^8.1.0` | `npm install awesome-cordova-plugins-reteno@8 @awesome-cordova-plugins/core@8` |
|
|
39
|
+
| `awesome-cordova-plugins-reteno@9` | `^9.1.2` | `npm install awesome-cordova-plugins-reteno@9 @awesome-cordova-plugins/core@9` |
|
|
40
|
+
|
|
41
|
+
If you already have `@awesome-cordova-plugins/core` installed, keep that major and install the matching wrapper:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
# Example: core already at v8 — install wrapper v8
|
|
45
|
+
npm install awesome-cordova-plugins-reteno@8
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Fresh install of latest:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npm install awesome-cordova-plugins-reteno @awesome-cordova-plugins/core
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Register provider
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno';
|
|
58
|
+
|
|
59
|
+
@NgModule({
|
|
60
|
+
providers: [AwesomeCordovaPluginReteno],
|
|
61
|
+
})
|
|
62
|
+
export class AppModule {}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Initialize the SDK
|
|
66
|
+
|
|
67
|
+
Call `init(...)` after `Platform.ready()`:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { Platform } from '@ionic/angular';
|
|
71
|
+
import { AwesomeCordovaPluginReteno } from 'awesome-cordova-plugins-reteno';
|
|
72
|
+
|
|
73
|
+
constructor(
|
|
74
|
+
private platform: Platform,
|
|
75
|
+
private reteno: AwesomeCordovaPluginReteno,
|
|
76
|
+
) {
|
|
77
|
+
this.platform.ready().then(async () => {
|
|
78
|
+
await this.reteno.init({
|
|
79
|
+
isDebugMode: false,
|
|
80
|
+
pauseInAppMessages: false,
|
|
81
|
+
pausePushInAppMessages: false,
|
|
82
|
+
inAppMessagesPauseBehaviour: 'POSTPONE_IN_APPS',
|
|
83
|
+
lifecycleTrackingOptions: {
|
|
84
|
+
appLifecycleEnabled: true,
|
|
85
|
+
foregroundLifecycleEnabled: false,
|
|
86
|
+
pushSubscriptionEnabled: true,
|
|
87
|
+
sessionStartEventsEnabled: true,
|
|
88
|
+
sessionEndEventsEnabled: true,
|
|
89
|
+
},
|
|
90
|
+
sessionDurationSeconds: 30 * 60,
|
|
91
|
+
isAutomaticScreenReportingEnabled: false, // iOS only
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Options reference
|
|
98
|
+
|
|
99
|
+
All fields are optional.
|
|
100
|
+
|
|
101
|
+
| Option | Type | iOS | Android | Notes |
|
|
102
|
+
|---|---|:---:|:---:|---|
|
|
103
|
+
| `accessKey` | `string` | ✅ | ✅ | Overrides `RETENO_ACCESS_KEY` (or legacy `SDK_ACCESS_KEY`) from `config.xml`. Usually not needed. |
|
|
104
|
+
| `isDebugMode` | `boolean` | ✅ | ✅ | Enables near real-time event monitoring for test devices. |
|
|
105
|
+
| `pauseInAppMessages` | `boolean` | ✅ | ✅ | Start SDK with in-app messages paused. |
|
|
106
|
+
| `pausePushInAppMessages` | `boolean` | — | ✅ | Android-only. Safe to pass on iOS (ignored). |
|
|
107
|
+
| `inAppMessagesPauseBehaviour` | `'SKIP_IN_APPS' \| 'POSTPONE_IN_APPS'` | ✅ | — | iOS-only via `init()`. On Android use runtime method in [InAppMessages](../InAppMessages/README.md). |
|
|
108
|
+
| `isAutomaticScreenReportingEnabled` | `boolean` | ✅ | — | iOS-only. Not recommended in hybrid WebView apps; use `logScreenView()` manually. |
|
|
109
|
+
| `lifecycleTrackingOptions` | `object \| 'ALL' \| 'NONE'` | ✅ | ✅ | See [App Lifecycle Events](../AppLifeCycleEvents/README.md). On iOS, set before/inside `init()`. |
|
|
110
|
+
| `sessionDurationSeconds` | `number` | ✅ | ✅ | Optional session reset duration (Android 2.9.4+, iOS 2.7.0+). |
|
|
111
|
+
|
|
112
|
+
### Access key
|
|
113
|
+
|
|
114
|
+
Recommended: set `RETENO_ACCESS_KEY` in `config.xml` (or via `ionic cordova plugin add --variable RETENO_ACCESS_KEY=...`). The plugin reads it automatically, so passing `accessKey` in JS is optional. The deprecated `SDK_ACCESS_KEY` name remains supported for backward compatibility.
|
|
115
|
+
|
|
116
|
+
### Calling `init()` multiple times
|
|
117
|
+
|
|
118
|
+
`init()` is idempotent: after first successful call, next calls resolve immediately without re-initializing native SDK. Options from later calls are ignored.
|
|
119
|
+
|
|
120
|
+
## TypeScript types
|
|
121
|
+
|
|
122
|
+
All payload and response types are exported from the wrapper package. Prefer them over `any` for better autocompletion and type safety:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import {
|
|
126
|
+
AwesomeCordovaPluginReteno,
|
|
127
|
+
RetenoInitializeOptions,
|
|
128
|
+
UserAttributes,
|
|
129
|
+
UserAttributesAnonymous,
|
|
130
|
+
SetUserAttributesPayload,
|
|
131
|
+
LogEventPayload,
|
|
132
|
+
LogEcommerceEventPayload,
|
|
133
|
+
NotificationPresentationOption,
|
|
134
|
+
InAppLifecyclePayload,
|
|
135
|
+
AppInboxMessage,
|
|
136
|
+
AppInboxMessages,
|
|
137
|
+
GetRecommendationsPayload,
|
|
138
|
+
RecommendationsResponse,
|
|
139
|
+
RetenoPushButtonClickedPayload,
|
|
140
|
+
} from 'awesome-cordova-plugins-reteno';
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Setup guides
|
|
144
|
+
|
|
145
|
+
- [iOS](./IOS.md)
|
|
146
|
+
- [Android](./Android.md)
|
|
147
|
+
|
|
148
|
+
Capacitor developers should use the dedicated sections inside platform setup guides:
|
|
149
|
+
|
|
150
|
+
- [Capacitor setup (iOS)](./IOS.md#capacitor-setup-ios)
|
|
151
|
+
- [Capacitor setup (Android)](./Android.md#capacitor-setup-android)
|
|
152
|
+
|
|
153
|
+
## Feature guides
|
|
154
|
+
|
|
155
|
+
- [Tracking user information](../Tracking%20user%20information/README.md)
|
|
156
|
+
- [Tracking user behaviour](../Tracking%20user%20behaviour/README.md)
|
|
157
|
+
- [Push notification](../Push%20notification/README.md)
|
|
158
|
+
- [In-app messages](../InAppMessages/README.md)
|
|
159
|
+
- [Ecommerce](../Ecommerce/README.md)
|
|
160
|
+
- [Recommendations](../Recommendations/README.md)
|
|
161
|
+
- [App Inbox](../AppInbox/README.md)
|
|
162
|
+
- [Action Buttons](../Action%20Buttons/README.md)
|
|
163
|
+
- [App Lifecycle Events](../AppLifeCycleEvents/README.md)
|
|
164
|
+
|
|
165
|
+
##### Licence
|
|
166
|
+
|
|
167
|
+
Reteno Cordova plugin is released under MIT. See [LICENSE](https://github.com/reteno-com/reteno-cordova/blob/main/LICENSE).
|