rn-erxes-sdk 0.1.25 → 0.2.0

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
@@ -87,267 +87,113 @@ erxes is composed of 2 main components: **XOS** & **Plugins**
87
87
 
88
88
  ## Usage
89
89
 
90
- <img src="https://raw.githubusercontent.com/erxes/rn-erxes-sdk/a7a111fafd30b71e34e99e618800b3110c2b57b6/Simulator%20Screenshot%20-%20iPhone%2014%20Pro%20Max%20-%202023-06-02%20at%2017.08.25.png" alt="screenshot" width="350">
90
+ <img src="https://raw.githubusercontent.com/erxes/rn-erxes-sdk/main/MOBILE-SDK.png" alt="rn-erxes-sdk messenger screenshot" width="350">
91
91
 
92
92
  ---
93
93
 
94
94
  # rn-erxes-sdk
95
95
 
96
- A React Native SDK for embedding the [erxes](https://erxes.io/) messenger experience inside a mobile application. It renders the erxes messenger UI, connects the visitor/customer to your erxes messenger integration, and handles conversations, unread counts, and message subscriptions for you.
96
+ A React Native bridge for the native SwiftUI erxes messenger
97
+ ([`erxes/erxes-ios-sdk`](https://github.com/erxes/erxes-ios-sdk) `0.30.0`).
97
98
 
98
- It works in Expo (managed) and bare React Native apps.
99
-
100
- ## Installation
101
-
102
- Install the SDK with Yarn:
103
-
104
- ```bash
105
- yarn add rn-erxes-sdk
99
+ ```tsx
100
+ import { ErxesNativeIOS } from 'rn-erxes-sdk';
106
101
  ```
107
102
 
108
- or npm:
103
+ ## Requirements
109
104
 
110
- ```bash
111
- npm install --save rn-erxes-sdk
112
- ```
105
+ | | |
106
+ |---|---|
107
+ | iOS | 16.0+ |
108
+ | Swift | 5.9+ |
109
+ | React Native | 0.81+ |
110
+ | Expo SDK | 53+ (development build or prebuild — Expo Go not supported) |
113
111
 
114
- These commands install the latest version published to **npm**. Pushing code to GitHub does **not** automatically update the npm package — a new version must be published explicitly (see [Maintainer workflow](#maintainer-workflow)).
112
+ ## Docs
115
113
 
116
- ## Required peer dependencies
114
+ - [Native iOS guide](docs/native-ios.md)
117
115
 
118
- The SDK relies on the following native packages, which must be installed in the host app:
119
-
120
- ```bash
121
- npx expo install @react-native-async-storage/async-storage
122
- yarn add react-native-get-random-values
123
- ```
116
+ ## Installation
124
117
 
125
- npm equivalent:
118
+ ### Bare React Native
126
119
 
127
120
  ```bash
128
- npx expo install @react-native-async-storage/async-storage
129
- npm install --save react-native-get-random-values
121
+ yarn add rn-erxes-sdk
122
+ cd ios && pod install
130
123
  ```
131
124
 
132
- - **`@react-native-async-storage/async-storage`** — required. Used to cache the customer id and conversation id between launches.
133
- - **`react-native-get-random-values`** — required. The SDK imports it internally to polyfill `crypto.getRandomValues`, which is used to generate a guest visitor id. It must be present in the host app's dependency tree.
134
-
135
- ### Optional
125
+ ### Expo
136
126
 
137
127
  ```bash
138
- npx expo install expo-image-picker
128
+ npx expo install rn-erxes-sdk expo-build-properties
139
129
  ```
140
130
 
141
- - **`expo-image-picker`** — optional. If installed, the messenger lets users attach images from their library. The SDK loads it lazily, so the attachment button is simply hidden when it is not installed. (Bare React Native apps may use `react-native-image-picker` instead — it is detected the same way.)
142
-
143
- ## Quick start with Expo
144
-
145
- ```bash
146
- npx create-expo-app@latest rn-erxes-sdk-test
147
- cd rn-erxes-sdk-test
131
+ Add to `app.json`:
148
132
 
149
- yarn add rn-erxes-sdk
150
- npx expo install @react-native-async-storage/async-storage
151
- yarn add react-native-get-random-values
152
-
153
- npx expo start --clear
133
+ ```json
134
+ {
135
+ "plugins": [
136
+ ["expo-build-properties", { "ios": { "deploymentTarget": "16.0" } }]
137
+ ]
138
+ }
154
139
  ```
155
140
 
156
- npm alternative:
157
-
158
141
  ```bash
159
- npm install --save rn-erxes-sdk
160
- npx expo install @react-native-async-storage/async-storage
161
- npm install --save react-native-get-random-values
162
-
163
- npx expo start --clear
142
+ npx expo prebuild --platform ios
143
+ cd ios && pod install
144
+ npx expo run:ios
164
145
  ```
165
146
 
166
- Render `<ErxesSDK />` from your app entry. In a classic Expo (`blank-typescript`) project that is `App.tsx`. In an Expo Router project the usage commonly lives in:
147
+ ## Usage
167
148
 
168
- ```text
169
- app/index.tsx
170
- ```
149
+ Call `configure` once at startup. It connects in the background so the messenger opens instantly.
171
150
 
172
- or:
151
+ ```tsx
152
+ import { ErxesNativeIOS } from 'rn-erxes-sdk';
173
153
 
174
- ```text
175
- src/app/index.tsx
154
+ ErxesNativeIOS.configure({
155
+ integrationId: 'YOUR_INTEGRATION_ID',
156
+ subDomain: 'yourcompany.erxes.io',
157
+ });
176
158
  ```
177
159
 
178
- ## Usage with Expo
179
-
180
- The example below separates three concerns:
181
-
182
- 1. authenticated customer-profile data taken from the host app's `currentUser` query,
183
- 2. browser/device/runtime metadata, and
184
- 3. the props passed to `ErxesSDK`.
160
+ Optionally identify the user:
185
161
 
186
162
  ```tsx
187
- import * as React from 'react';
188
- import { Platform, View } from 'react-native';
189
- import { ErxesSDK } from 'rn-erxes-sdk';
190
-
191
- type CurrentUser = {
192
- firstName?: string;
193
- lastName?: string;
194
- primaryEmail?: string;
195
- primaryPhone?: string;
196
- sex?: string | number;
197
- propertiesData?: Record<string, unknown>;
198
- };
199
-
200
- type Props = {
201
- currentUser?: CurrentUser;
202
- };
203
-
204
- export default function App({ currentUser }: Props) {
205
- const integrationId = 'YOUR_INTEGRATION_ID';
206
- const subDomain = 'YOUR_SUBDOMAIN.next.erxes.io';
207
-
208
- const data = {
209
- firstName: currentUser?.firstName ?? '',
210
- lastName: currentUser?.lastName ?? '',
211
- primaryEmail: currentUser?.primaryEmail ?? '',
212
- sex: currentUser?.sex ?? '',
213
- Type: 'mobile',
214
- ...currentUser?.propertiesData,
215
- };
216
-
217
- const properties = {
218
- remoteAddress: '',
219
- region: '',
220
- countryCode: '',
221
- city: '',
222
- country: '',
223
- url: 'https://YOUR_SUBDOMAIN.nextwidgets.erxes.io/',
224
- hostname: 'YOUR_SUBDOMAIN.nextwidgets.erxes.io',
225
- language: 'en-US',
226
- userAgent: Platform.OS,
227
- };
228
-
229
- return (
230
- <View style={{ flex: 1 }}>
231
- <ErxesSDK
232
- integrationId={integrationId}
233
- subDomain={subDomain}
234
- onBack={() => console.log('onBack')}
235
- showWidget={false}
236
- phone={currentUser?.primaryPhone ?? ''}
237
- data={data}
238
- properties={properties}
239
- />
240
- </View>
241
- );
242
- }
163
+ ErxesNativeIOS.setUser({
164
+ email: 'user@example.com',
165
+ name: 'Jane Doe',
166
+ customData: { plan: 'pro' },
167
+ });
243
168
  ```
244
169
 
245
- Notes:
170
+ ### Option A — Floating launcher (recommended)
246
171
 
247
- - The exact `currentUser` query depends on your host application the SDK does not provide it.
248
- - `data` should normally be mapped from the authenticated user's query result rather than hardcoded.
249
- - Do not hardcode private customer information in production.
250
- - Empty property values are acceptable when metadata is unavailable.
251
- - Do not fake IP addresses or location values.
252
- - Replace `YOUR_INTEGRATION_ID` and `YOUR_SUBDOMAIN` with the values from your erxes environment.
253
- - `Platform.OS` is only a lightweight fallback for `userAgent`; it is not a complete browser user-agent string.
254
-
255
- ## Customer data from `currentUser`
256
-
257
- `data` is customer-profile information. It is forwarded to the erxes `widgetsMessengerConnect` mutation (as the `data` JSON argument) when the SDK connects, and is used to create or identify the customer.
172
+ Shows a draggable button over your app. Tapping it opens the messenger automatically.
258
173
 
259
174
  ```tsx
260
- const data = {
261
- firstName: currentUser?.firstName ?? '',
262
- lastName: currentUser?.lastName ?? '',
263
- primaryEmail: currentUser?.primaryEmail ?? '',
264
- sex: currentUser?.sex ?? '',
265
- Type: 'mobile',
266
- ...currentUser?.propertiesData,
267
- };
175
+ ErxesNativeIOS.showLauncher();
176
+ // ErxesNativeIOS.hideLauncher(); // to remove it
268
177
  ```
269
178
 
270
- - This normally comes from the host application's authenticated-user query.
271
- - Custom fields may be included when relevant (e.g. spread from `propertiesData`).
272
- - `data` is optional — when omitted, the visitor is connected as a guest.
273
- - Do not use fake values in production.
274
-
275
- ## Browser and device information
179
+ ### Option B Your own button
276
180
 
277
- `properties` describes the browser, device, and runtime environment. When the SDK has an identified customer, it sends these values to the erxes `widgetsSaveBrowserInfo` mutation internally — **you do not call it yourself**, you only pass the `properties` prop.
181
+ If you have a custom trigger in your UI, call `showMessenger()` directly:
278
182
 
279
183
  ```tsx
280
- const properties = {
281
- remoteAddress: '',
282
- region: '',
283
- countryCode: '',
284
- city: '',
285
- country: '',
286
- url: 'https://YOUR_SUBDOMAIN.nextwidgets.erxes.io/',
287
- hostname: 'YOUR_SUBDOMAIN.nextwidgets.erxes.io',
288
- language: 'en-US',
289
- userAgent: 'DEVICE_USER_AGENT',
290
- };
184
+ <Button title="Support" onPress={() => ErxesNativeIOS.showMessenger()} />
291
185
  ```
292
186
 
293
- - Empty strings are acceptable when a value is unavailable.
294
- - Do not fake IP addresses or location values.
295
- - Collect real runtime values where possible.
296
-
297
- For reference, the mutation the SDK calls internally is:
298
-
299
- ```graphql
300
- mutation widgetsSaveBrowserInfo(
301
- $customerId: String
302
- $visitorId: String
303
- $browserInfo: JSON!
304
- ) {
305
- widgetsSaveBrowserInfo(
306
- customerId: $customerId
307
- visitorId: $visitorId
308
- browserInfo: $browserInfo
309
- ) {
310
- _id
311
- conversationId
312
- customerId
313
- }
314
- }
315
- ```
316
-
317
- The SDK passes the connected `customerId` together with your `properties` object as `browserInfo`. The customer id and visitor id are managed by the SDK:
318
-
319
- - On first launch the SDK generates a guest **visitor id** (a 24-character hex string) and uses it to connect.
320
- - After connecting, the resolved **customer id** is cached in `AsyncStorage` and reused on later launches.
187
+ On logout:
321
188
 
322
- You only pass the relevant props (`data`, `properties`, `phone`); you should not duplicate this connect / save-browser-info flow yourself.
323
-
324
- ## Props
325
-
326
- Public props of `ErxesSDK` (from the SDK's TypeScript types):
189
+ ```tsx
190
+ ErxesNativeIOS.clearUser();
191
+ ```
327
192
 
328
- | Prop | Type | Required | Description |
329
- | --- | --- | --- | --- |
330
- | `integrationId` | `string` | Yes | erxes messenger integration id used to connect. |
331
- | `subDomain` | `string` | Yes | erxes environment subdomain (e.g. `YOUR_SUBDOMAIN.next.erxes.io`); used to build the GraphQL/WS endpoints and asset URLs. |
332
- | `showWidget` | `boolean` | Yes | When `true`, renders the floating launcher button; when `false`, renders the messenger inline. |
333
- | `brandCode` | `string` | No | Brand code; used as a fallback when `integrationId` is not provided. |
334
- | `email` | `string` | No | When set, the contact is connected as an identified user (`isUser`). |
335
- | `onBack` | `() => void` | No | Called when the user navigates back from the messenger. |
336
- | `phone` | `string` | No | Phone number used to identify the customer on connect. |
337
- | `data` | `object` | No | Customer-profile data forwarded to `widgetsMessengerConnect`. |
338
- | `properties` | `object` | No | Browser/device metadata sent as `browserInfo` to `widgetsSaveBrowserInfo`. |
339
- | `backIcon` | `ImageSource` | No | Custom back icon. |
340
- | `newChatIcon` | `ImageSource` | No | Custom "new chat" icon. |
341
- | `sendIcon` | `ImageSource` | No | Custom send icon. |
193
+ Full example: [Native iOS guide](docs/native-ios.md).
342
194
 
343
195
  ## Troubleshooting
344
196
 
345
- ### Clear Expo cache
346
-
347
- ```bash
348
- npx expo start --clear
349
- ```
350
-
351
197
  ### Confirm the installed version
352
198
 
353
199
  ```bash
@@ -364,30 +210,25 @@ npm ls rn-erxes-sdk
364
210
 
365
211
  ```bash
366
212
  yarn add rn-erxes-sdk@latest
367
- npx expo start --clear
368
213
  ```
369
214
 
370
215
  or:
371
216
 
372
217
  ```bash
373
218
  npm install --save rn-erxes-sdk@latest
374
- npx expo start --clear
375
219
  ```
376
220
 
377
- ### Native dependencies
378
-
379
- The required peer dependencies (`@react-native-async-storage/async-storage`, `react-native-get-random-values`) must be installed in the **host app**. The SDK does not bundle them.
380
-
381
- ### `await is not defined` (BSON Metro crash)
221
+ After upgrading, reinstall pods and rebuild the app:
382
222
 
383
- Older SDK releases depended on `bson`, which could cause Metro/Hermes to crash at startup with:
384
-
385
- ```text
386
- await is not defined
387
- node_modules/bson/lib/bson.mjs
223
+ ```bash
224
+ cd ios
225
+ pod install
388
226
  ```
389
227
 
390
- This happened because Expo resolves packages through their ESM `exports` map and picked `bson/lib/bson.mjs`, which uses a top-level `await`. **Upgrade to the latest `rn-erxes-sdk` release** — it no longer depends on `bson`. A custom Metro config change is not required.
228
+ ### Expo Go
229
+
230
+ This package uses native Swift code and does not run in Expo Go. Use an Expo
231
+ development build or a bare React Native app.
391
232
 
392
233
  ## Maintainer workflow
393
234
 
@@ -0,0 +1,170 @@
1
+ # Native iOS Guide
2
+
3
+ `ErxesNativeIOS` bridges the native SwiftUI erxes messenger
4
+ ([`erxes/erxes-ios-sdk`](https://github.com/erxes/erxes-ios-sdk) `0.30.0`)
5
+ into your React Native app.
6
+
7
+ ## Requirements
8
+
9
+ | | |
10
+ |---|---|
11
+ | iOS | 16.0+ |
12
+ | Swift | 5.9+ |
13
+ | React Native | 0.81+ |
14
+ | Expo SDK | 53+ (development build or prebuild only — Expo Go not supported) |
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ### Bare React Native
21
+
22
+ ```bash
23
+ yarn add rn-erxes-sdk
24
+ cd ios && pod install
25
+ ```
26
+
27
+ ### Expo
28
+
29
+ Expo Go cannot load custom native modules. You need a development build or prebuild.
30
+
31
+ ```bash
32
+ npx expo install rn-erxes-sdk expo-build-properties
33
+ ```
34
+
35
+ Set the minimum iOS deployment target in `app.json`:
36
+
37
+ ```json
38
+ {
39
+ "plugins": [
40
+ ["expo-build-properties", { "ios": { "deploymentTarget": "16.0" } }]
41
+ ]
42
+ }
43
+ ```
44
+
45
+ Prebuild and install pods:
46
+
47
+ ```bash
48
+ npx expo prebuild --platform ios
49
+ cd ios && pod install
50
+ npx expo run:ios
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Setup
56
+
57
+ Call `configure` once at app startup (e.g. inside `useEffect` in your root component). This starts the connection handshake in the background so the messenger is ready instantly when the user opens it.
58
+
59
+ ```tsx
60
+ import { ErxesNativeIOS } from 'rn-erxes-sdk';
61
+
62
+ ErxesNativeIOS.configure({
63
+ integrationId: 'YOUR_INTEGRATION_ID',
64
+ subDomain: 'yourcompany.erxes.io',
65
+ });
66
+ ```
67
+
68
+ You can pass `endpoint` instead of `subDomain`:
69
+
70
+ ```tsx
71
+ ErxesNativeIOS.configure({
72
+ integrationId: 'YOUR_INTEGRATION_ID',
73
+ endpoint: 'https://yourcompany.erxes.io',
74
+ });
75
+ ```
76
+
77
+ Optionally identify the logged-in user:
78
+
79
+ ```tsx
80
+ ErxesNativeIOS.setUser({
81
+ email: 'user@example.com',
82
+ phone: '+15551234567',
83
+ name: 'Jane Doe',
84
+ customData: { plan: 'pro' }, // any key-value pairs
85
+ });
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Showing the messenger
91
+
92
+ There are two ways to let users open the messenger. Pick one.
93
+
94
+ ### Option A — Floating launcher button (recommended)
95
+
96
+ Call `showLauncher()` after `configure()`. A draggable floating button appears on screen automatically once the SDK connects. The user taps it to open the messenger. No extra code needed.
97
+
98
+ ```tsx
99
+ ErxesNativeIOS.configure({ integrationId, subDomain });
100
+ ErxesNativeIOS.showLauncher();
101
+ ```
102
+
103
+ To remove the launcher (e.g. on certain screens or after logout):
104
+
105
+ ```tsx
106
+ ErxesNativeIOS.hideLauncher();
107
+ ```
108
+
109
+ ### Option B — Your own button
110
+
111
+ If you have a custom button, tab, or trigger in your own UI, call `showMessenger()` directly. Skip `showLauncher()`.
112
+
113
+ ```tsx
114
+ ErxesNativeIOS.configure({ integrationId, subDomain });
115
+
116
+ // somewhere in your UI:
117
+ <Button title="Support" onPress={() => ErxesNativeIOS.showMessenger()} />
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Logout
123
+
124
+ Clear the user when they log out of your app:
125
+
126
+ ```tsx
127
+ ErxesNativeIOS.clearUser();
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Full example
133
+
134
+ ```tsx
135
+ import React, { useEffect } from 'react';
136
+ import { View, Button } from 'react-native';
137
+ import { ErxesNativeIOS } from 'rn-erxes-sdk';
138
+
139
+ export default function App() {
140
+ useEffect(() => {
141
+ ErxesNativeIOS.configure({
142
+ integrationId: 'YOUR_INTEGRATION_ID',
143
+ subDomain: 'yourcompany.erxes.io',
144
+ primaryColor: '#3f78d9',
145
+ });
146
+
147
+ ErxesNativeIOS.setUser({
148
+ email: 'user@example.com',
149
+ name: 'Jane Doe',
150
+ });
151
+
152
+ // Show floating launcher — remove this if you use your own button instead
153
+ ErxesNativeIOS.showLauncher();
154
+ }, []);
155
+
156
+ return <View style={{ flex: 1 }} />;
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Troubleshooting
163
+
164
+ **Native module not found** — run `pod install` and rebuild:
165
+ ```bash
166
+ cd ios && pod install
167
+ npx react-native run-ios # or: npx expo run:ios
168
+ ```
169
+
170
+ **Expo Go** — not supported. Build a development client with `npx expo run:ios`.
@@ -0,0 +1,25 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RCT_EXTERN_MODULE(RnErxesSdk, NSObject)
4
+
5
+ RCT_EXTERN_METHOD(configure:(NSDictionary *)options
6
+ resolver:(RCTPromiseResolveBlock)resolve
7
+ rejecter:(RCTPromiseRejectBlock)reject)
8
+
9
+ RCT_EXTERN_METHOD(setUser:(NSDictionary *)options
10
+ resolver:(RCTPromiseResolveBlock)resolve
11
+ rejecter:(RCTPromiseRejectBlock)reject)
12
+
13
+ RCT_EXTERN_METHOD(clearUser:(RCTPromiseResolveBlock)resolve
14
+ rejecter:(RCTPromiseRejectBlock)reject)
15
+
16
+ RCT_EXTERN_METHOD(showMessenger:(RCTPromiseResolveBlock)resolve
17
+ rejecter:(RCTPromiseRejectBlock)reject)
18
+
19
+ RCT_EXTERN_METHOD(showLauncher:(RCTPromiseResolveBlock)resolve
20
+ rejecter:(RCTPromiseRejectBlock)reject)
21
+
22
+ RCT_EXTERN_METHOD(hideLauncher:(RCTPromiseResolveBlock)resolve
23
+ rejecter:(RCTPromiseRejectBlock)reject)
24
+
25
+ @end
@@ -0,0 +1,189 @@
1
+ import Foundation
2
+ import MessengerSDK
3
+ import UIKit
4
+ import React
5
+
6
+ @objc(RnErxesSdk)
7
+ final class RnErxesSdk: NSObject {
8
+ @objc
9
+ static func requiresMainQueueSetup() -> Bool {
10
+ true
11
+ }
12
+
13
+ @objc(configure:resolver:rejecter:)
14
+ func configure(
15
+ _ options: NSDictionary,
16
+ resolver resolve: @escaping RCTPromiseResolveBlock,
17
+ rejecter reject: @escaping RCTPromiseRejectBlock
18
+ ) {
19
+ Task { @MainActor in
20
+ guard let integrationId = options["integrationId"] as? String, !integrationId.isEmpty else {
21
+ reject("missing_integration_id", "integrationId is required", nil)
22
+ return
23
+ }
24
+
25
+ guard let endpoint = Self.endpoint(from: options) else {
26
+ reject("missing_endpoint", "endpoint, serverUrl, or subDomain is required", nil)
27
+ return
28
+ }
29
+
30
+ let cachedCustomerId = Self.string(options["cachedCustomerId"])
31
+
32
+ MessengerSDK.configure(
33
+ MessengerConfig(
34
+ endpoint: endpoint,
35
+ integrationId: integrationId,
36
+ cachedCustomerId: cachedCustomerId
37
+ )
38
+ )
39
+
40
+ resolve(nil)
41
+ }
42
+ }
43
+
44
+ @objc(setUser:resolver:rejecter:)
45
+ func setUser(
46
+ _ options: NSDictionary,
47
+ resolver resolve: @escaping RCTPromiseResolveBlock,
48
+ rejecter reject: @escaping RCTPromiseRejectBlock
49
+ ) {
50
+ Task { @MainActor in
51
+ let email = Self.string(options["email"])
52
+ let phone = Self.string(options["phone"])
53
+ let name = Self.string(options["name"])
54
+ let customData = Self.stringDictionary(options["customData"])
55
+
56
+ MessengerSDK.setUser(
57
+ MessengerUser(
58
+ email: email,
59
+ phone: phone,
60
+ name: name,
61
+ customData: customData
62
+ )
63
+ )
64
+
65
+ resolve(nil)
66
+ }
67
+ }
68
+
69
+ @objc(clearUser:rejecter:)
70
+ func clearUser(
71
+ _ resolve: @escaping RCTPromiseResolveBlock,
72
+ rejecter reject: @escaping RCTPromiseRejectBlock
73
+ ) {
74
+ Task { @MainActor in
75
+ MessengerSDK.clearUser()
76
+ resolve(nil)
77
+ }
78
+ }
79
+
80
+ @objc(showMessenger:rejecter:)
81
+ func showMessenger(
82
+ _ resolve: @escaping RCTPromiseResolveBlock,
83
+ rejecter reject: @escaping RCTPromiseRejectBlock
84
+ ) {
85
+ Task { @MainActor in
86
+ guard let presenter = Self.topViewController() else {
87
+ reject("missing_presenter", "Unable to find a view controller to present from", nil)
88
+ return
89
+ }
90
+
91
+ MessengerSDK.showMessenger(from: presenter)
92
+ resolve(nil)
93
+ }
94
+ }
95
+
96
+ @objc(showLauncher:rejecter:)
97
+ func showLauncher(
98
+ _ resolve: @escaping RCTPromiseResolveBlock,
99
+ rejecter reject: @escaping RCTPromiseRejectBlock
100
+ ) {
101
+ Task { @MainActor in
102
+ MessengerSDK.showLauncher()
103
+ resolve(nil)
104
+ }
105
+ }
106
+
107
+ @objc(hideLauncher:rejecter:)
108
+ func hideLauncher(
109
+ _ resolve: @escaping RCTPromiseResolveBlock,
110
+ rejecter reject: @escaping RCTPromiseRejectBlock
111
+ ) {
112
+ Task { @MainActor in
113
+ MessengerSDK.hideLauncher()
114
+ resolve(nil)
115
+ }
116
+ }
117
+
118
+ private static func endpoint(from options: NSDictionary) -> String? {
119
+ if let endpoint = string(options["endpoint"]) ?? string(options["serverUrl"]) {
120
+ return endpoint
121
+ }
122
+
123
+ guard let subDomain = string(options["subDomain"]) else {
124
+ return nil
125
+ }
126
+
127
+ if subDomain.hasPrefix("http://") || subDomain.hasPrefix("https://") {
128
+ return subDomain
129
+ }
130
+
131
+ return "https://\(subDomain)"
132
+ }
133
+
134
+ private static func string(_ value: Any?) -> String? {
135
+ guard let value else { return nil }
136
+
137
+ if let value = value as? String {
138
+ return value.isEmpty ? nil : value
139
+ }
140
+
141
+ if let value = value as? NSNumber {
142
+ return value.stringValue
143
+ }
144
+
145
+ return nil
146
+ }
147
+
148
+ private static func stringDictionary(_ value: Any?) -> [String: String] {
149
+ guard let dictionary = value as? [String: Any] else {
150
+ return [:]
151
+ }
152
+
153
+ return dictionary.reduce(into: [String: String]()) { result, item in
154
+ if let stringValue = string(item.value) {
155
+ result[item.key] = stringValue
156
+ }
157
+ }
158
+ }
159
+
160
+ @MainActor
161
+ private static func topViewController() -> UIViewController? {
162
+ topViewController(from: keyWindow()?.rootViewController)
163
+ }
164
+
165
+ @MainActor
166
+ private static func topViewController(from root: UIViewController?) -> UIViewController? {
167
+ if let navigation = root as? UINavigationController {
168
+ return topViewController(from: navigation.visibleViewController)
169
+ }
170
+
171
+ if let tab = root as? UITabBarController {
172
+ return topViewController(from: tab.selectedViewController)
173
+ }
174
+
175
+ if let presented = root?.presentedViewController {
176
+ return topViewController(from: presented)
177
+ }
178
+
179
+ return root
180
+ }
181
+
182
+ @MainActor
183
+ private static func keyWindow() -> UIWindow? {
184
+ UIApplication.shared.connectedScenes
185
+ .compactMap { $0 as? UIWindowScene }
186
+ .flatMap(\.windows)
187
+ .first { $0.isKeyWindow }
188
+ }
189
+ }
@@ -3,12 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "ErxesSDK", {
6
+ Object.defineProperty(exports, "ErxesNativeIOS", {
7
7
  enumerable: true,
8
8
  get: function () {
9
- return _App.default;
9
+ return _nativeIos.ErxesNativeIOS;
10
10
  }
11
11
  });
12
- var _App = _interopRequireDefault(require("./App"));
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ var _nativeIos = require("./nativeIos");
14
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_App","_interopRequireDefault","require","obj","__esModule","default"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;AAAA,IAAAA,IAAA,GAAAC,sBAAA,CAAAC,OAAA;AAA4C,SAAAD,uBAAAE,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA"}
1
+ {"version":3,"names":["_nativeIos","require"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ErxesNativeIOS = void 0;
7
+ var _reactNative = require("react-native");
8
+ const LINKING_ERROR = "The rn-erxes-sdk native iOS module is not linked. Run `pod install` in your app's ios directory and rebuild the app.";
9
+ const nativeModule = _reactNative.NativeModules.RnErxesSdk;
10
+ function getNativeModule() {
11
+ if (_reactNative.Platform.OS !== 'ios') {
12
+ throw new Error('Erxes native messenger is only available on iOS.');
13
+ }
14
+ if (!nativeModule) {
15
+ throw new Error(LINKING_ERROR);
16
+ }
17
+ return nativeModule;
18
+ }
19
+ const ErxesNativeIOS = {
20
+ configure(options) {
21
+ return getNativeModule().configure(options);
22
+ },
23
+ setUser(options) {
24
+ const customData = Object.fromEntries(Object.entries(options.customData ?? {}).filter(_ref => {
25
+ let [, value] = _ref;
26
+ return value !== null && value !== undefined;
27
+ }).map(_ref2 => {
28
+ let [key, value] = _ref2;
29
+ return [key, String(value)];
30
+ }));
31
+ return getNativeModule().setUser({
32
+ ...options,
33
+ customData
34
+ });
35
+ },
36
+ clearUser() {
37
+ return getNativeModule().clearUser();
38
+ },
39
+ showMessenger() {
40
+ return getNativeModule().showMessenger();
41
+ },
42
+ showLauncher() {
43
+ return getNativeModule().showLauncher();
44
+ },
45
+ hideLauncher() {
46
+ return getNativeModule().hideLauncher();
47
+ }
48
+ };
49
+ exports.ErxesNativeIOS = ErxesNativeIOS;
50
+ //# sourceMappingURL=nativeIos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","nativeModule","NativeModules","RnErxesSdk","getNativeModule","Platform","OS","Error","ErxesNativeIOS","configure","options","setUser","customData","Object","fromEntries","entries","filter","_ref","value","undefined","map","_ref2","key","String","clearUser","showMessenger","showLauncher","hideLauncher","exports"],"sourceRoot":"../../src","sources":["nativeIos.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AA0BA,MAAMC,aAAa,GACjB,sHAAsH;AAExH,MAAMC,YAAY,GAAGC,0BAAa,CAACC,UAAyC;AAE5E,SAASC,eAAeA,CAAA,EAAoB;EAC1C,IAAIC,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;IACzB,MAAM,IAAIC,KAAK,CAAC,kDAAkD,CAAC;EACrE;EAEA,IAAI,CAACN,YAAY,EAAE;IACjB,MAAM,IAAIM,KAAK,CAACP,aAAa,CAAC;EAChC;EAEA,OAAOC,YAAY;AACrB;AAEO,MAAMO,cAAc,GAAG;EAC5BC,SAASA,CAACC,OAAwB,EAAE;IAClC,OAAON,eAAe,CAAC,CAAC,CAACK,SAAS,CAACC,OAAO,CAAC;EAC7C,CAAC;EACDC,OAAOA,CAACD,OAAsB,EAAE;IAC9B,MAAME,UAAU,GAAGC,MAAM,CAACC,WAAW,CACnCD,MAAM,CAACE,OAAO,CAACL,OAAO,CAACE,UAAU,IAAI,CAAC,CAAC,CAAC,CACrCI,MAAM,CAACC,IAAA;MAAA,IAAC,GAAGC,KAAK,CAAC,GAAAD,IAAA;MAAA,OAAKC,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKC,SAAS;IAAA,EAAC,CAC5DC,GAAG,CAACC,KAAA;MAAA,IAAC,CAACC,GAAG,EAAEJ,KAAK,CAAC,GAAAG,KAAA;MAAA,OAAK,CAACC,GAAG,EAAEC,MAAM,CAACL,KAAK,CAAC,CAAC;IAAA,EAC/C,CAAC;IAED,OAAOd,eAAe,CAAC,CAAC,CAACO,OAAO,CAAC;MAC/B,GAAGD,OAAO;MACVE;IACF,CAAC,CAAC;EACJ,CAAC;EACDY,SAASA,CAAA,EAAG;IACV,OAAOpB,eAAe,CAAC,CAAC,CAACoB,SAAS,CAAC,CAAC;EACtC,CAAC;EACDC,aAAaA,CAAA,EAAG;IACd,OAAOrB,eAAe,CAAC,CAAC,CAACqB,aAAa,CAAC,CAAC;EAC1C,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOtB,eAAe,CAAC,CAAC,CAACsB,YAAY,CAAC,CAAC;EACzC,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOvB,eAAe,CAAC,CAAC,CAACuB,YAAY,CAAC,CAAC;EACzC;AACF,CAAC;AAACC,OAAA,CAAApB,cAAA,GAAAA,cAAA"}
@@ -1,2 +1,2 @@
1
- export { default as ErxesSDK } from './App';
1
+ export { ErxesNativeIOS } from './nativeIos';
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["default","ErxesSDK"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,OAAO,IAAIC,QAAQ,QAAQ,OAAO"}
1
+ {"version":3,"names":["ErxesNativeIOS"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,cAAc,QAAQ,aAAa"}
@@ -0,0 +1,43 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+ const LINKING_ERROR = "The rn-erxes-sdk native iOS module is not linked. Run `pod install` in your app's ios directory and rebuild the app.";
3
+ const nativeModule = NativeModules.RnErxesSdk;
4
+ function getNativeModule() {
5
+ if (Platform.OS !== 'ios') {
6
+ throw new Error('Erxes native messenger is only available on iOS.');
7
+ }
8
+ if (!nativeModule) {
9
+ throw new Error(LINKING_ERROR);
10
+ }
11
+ return nativeModule;
12
+ }
13
+ export const ErxesNativeIOS = {
14
+ configure(options) {
15
+ return getNativeModule().configure(options);
16
+ },
17
+ setUser(options) {
18
+ const customData = Object.fromEntries(Object.entries(options.customData ?? {}).filter(_ref => {
19
+ let [, value] = _ref;
20
+ return value !== null && value !== undefined;
21
+ }).map(_ref2 => {
22
+ let [key, value] = _ref2;
23
+ return [key, String(value)];
24
+ }));
25
+ return getNativeModule().setUser({
26
+ ...options,
27
+ customData
28
+ });
29
+ },
30
+ clearUser() {
31
+ return getNativeModule().clearUser();
32
+ },
33
+ showMessenger() {
34
+ return getNativeModule().showMessenger();
35
+ },
36
+ showLauncher() {
37
+ return getNativeModule().showLauncher();
38
+ },
39
+ hideLauncher() {
40
+ return getNativeModule().hideLauncher();
41
+ }
42
+ };
43
+ //# sourceMappingURL=nativeIos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","nativeModule","RnErxesSdk","getNativeModule","OS","Error","ErxesNativeIOS","configure","options","setUser","customData","Object","fromEntries","entries","filter","_ref","value","undefined","map","_ref2","key","String","clearUser","showMessenger","showLauncher","hideLauncher"],"sourceRoot":"../../src","sources":["nativeIos.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AA0BtD,MAAMC,aAAa,GACjB,sHAAsH;AAExH,MAAMC,YAAY,GAAGH,aAAa,CAACI,UAAyC;AAE5E,SAASC,eAAeA,CAAA,EAAoB;EAC1C,IAAIJ,QAAQ,CAACK,EAAE,KAAK,KAAK,EAAE;IACzB,MAAM,IAAIC,KAAK,CAAC,kDAAkD,CAAC;EACrE;EAEA,IAAI,CAACJ,YAAY,EAAE;IACjB,MAAM,IAAII,KAAK,CAACL,aAAa,CAAC;EAChC;EAEA,OAAOC,YAAY;AACrB;AAEA,OAAO,MAAMK,cAAc,GAAG;EAC5BC,SAASA,CAACC,OAAwB,EAAE;IAClC,OAAOL,eAAe,CAAC,CAAC,CAACI,SAAS,CAACC,OAAO,CAAC;EAC7C,CAAC;EACDC,OAAOA,CAACD,OAAsB,EAAE;IAC9B,MAAME,UAAU,GAAGC,MAAM,CAACC,WAAW,CACnCD,MAAM,CAACE,OAAO,CAACL,OAAO,CAACE,UAAU,IAAI,CAAC,CAAC,CAAC,CACrCI,MAAM,CAACC,IAAA;MAAA,IAAC,GAAGC,KAAK,CAAC,GAAAD,IAAA;MAAA,OAAKC,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKC,SAAS;IAAA,EAAC,CAC5DC,GAAG,CAACC,KAAA;MAAA,IAAC,CAACC,GAAG,EAAEJ,KAAK,CAAC,GAAAG,KAAA;MAAA,OAAK,CAACC,GAAG,EAAEC,MAAM,CAACL,KAAK,CAAC,CAAC;IAAA,EAC/C,CAAC;IAED,OAAOb,eAAe,CAAC,CAAC,CAACM,OAAO,CAAC;MAC/B,GAAGD,OAAO;MACVE;IACF,CAAC,CAAC;EACJ,CAAC;EACDY,SAASA,CAAA,EAAG;IACV,OAAOnB,eAAe,CAAC,CAAC,CAACmB,SAAS,CAAC,CAAC;EACtC,CAAC;EACDC,aAAaA,CAAA,EAAG;IACd,OAAOpB,eAAe,CAAC,CAAC,CAACoB,aAAa,CAAC,CAAC;EAC1C,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOrB,eAAe,CAAC,CAAC,CAACqB,YAAY,CAAC,CAAC;EACzC,CAAC;EACDC,YAAYA,CAAA,EAAG;IACb,OAAOtB,eAAe,CAAC,CAAC,CAACsB,YAAY,CAAC,CAAC;EACzC;AACF,CAAC"}
@@ -1,2 +1,3 @@
1
- export { default as ErxesSDK } from './App';
1
+ export { ErxesNativeIOS } from './nativeIos';
2
+ export type { NativeIOSConfig, NativeIOSUser } from './nativeIos';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,23 @@
1
+ type NativeIOSConfig = {
2
+ integrationId: string;
3
+ endpoint?: string;
4
+ serverUrl?: string;
5
+ subDomain?: string;
6
+ cachedCustomerId?: string;
7
+ };
8
+ type NativeIOSUser = {
9
+ email?: string;
10
+ phone?: string;
11
+ name?: string;
12
+ customData?: Record<string, string | number | boolean | null | undefined>;
13
+ };
14
+ export declare const ErxesNativeIOS: {
15
+ configure(options: NativeIOSConfig): Promise<void>;
16
+ setUser(options: NativeIOSUser): Promise<void>;
17
+ clearUser(): Promise<void>;
18
+ showMessenger(): Promise<void>;
19
+ showLauncher(): Promise<void>;
20
+ hideLauncher(): Promise<void>;
21
+ };
22
+ export type { NativeIOSConfig, NativeIOSUser };
23
+ //# sourceMappingURL=nativeIos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeIos.d.ts","sourceRoot":"","sources":["../../src/nativeIos.ts"],"names":[],"mappings":"AAEA,KAAK,eAAe,GAAG;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CAC3E,CAAC;AA4BF,eAAO,MAAM,cAAc;uBACN,eAAe;qBAGjB,aAAa;;;;;CAwB/B,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-erxes-sdk",
3
- "version": "0.1.25",
3
+ "version": "0.2.0",
4
4
  "description": "react-native erxes sdk",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -10,8 +10,10 @@
10
10
  "files": [
11
11
  "src",
12
12
  "lib",
13
+ "docs",
13
14
  "android",
14
- "ios",
15
+ "ios/RnErxesSdk.m",
16
+ "ios/RnErxesSdk.swift",
15
17
  "cpp",
16
18
  "*.podspec",
17
19
  "!lib/typescript/example",
@@ -81,16 +83,8 @@
81
83
  "typescript": "^4.5.2"
82
84
  },
83
85
  "peerDependencies": {
84
- "@react-native-async-storage/async-storage": ">=2.2.0",
85
86
  "react": "*",
86
- "react-native": "*",
87
- "react-native-get-random-values": ">=1.11.0",
88
- "expo-image-picker": "*"
89
- },
90
- "peerDependenciesMeta": {
91
- "expo-image-picker": {
92
- "optional": true
93
- }
87
+ "react-native": "*"
94
88
  },
95
89
  "engines": {
96
90
  "node": ">=20.19.0"
@@ -0,0 +1,45 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ begin
6
+ react_native_pods = Pod::Executable.execute_command(
7
+ 'node',
8
+ [
9
+ '-p',
10
+ 'require.resolve("react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]})',
11
+ __dir__
12
+ ]
13
+ ).strip
14
+ require react_native_pods
15
+ rescue StandardError
16
+ # React Native Podfiles normally load react_native_pods.rb before evaluating
17
+ # package podspecs. This fallback keeps podspec parsing useful in isolation.
18
+ end
19
+
20
+ Pod::Spec.new do |s|
21
+ s.name = 'rn-erxes-sdk'
22
+ s.version = package['version']
23
+ s.summary = package['description']
24
+ s.description = package['description']
25
+ s.homepage = package['homepage']
26
+ s.license = package['license']
27
+ s.author = package['author']
28
+ s.platforms = { :ios => '16.0' }
29
+ s.source = { :git => 'https://github.com/erxes/rn-erxes-sdk.git', :tag => "v#{s.version}" }
30
+ s.source_files = 'ios/RnErxesSdk.{m,swift}'
31
+ s.swift_version = '5.9'
32
+
33
+ s.dependency 'React-Core'
34
+
35
+ if defined?(spm_dependency)
36
+ spm_dependency(
37
+ s,
38
+ url: 'https://github.com/Munkhorgilb/ios-sdk.git',
39
+ requirement: { :kind => 'exactVersion', :version => '0.30.0' },
40
+ products: ['MessengerSDK']
41
+ )
42
+ else
43
+ raise 'rn-erxes-sdk requires React Native 0.81+ CocoaPods SPM support to install MessengerSDK 0.0.1'
44
+ end
45
+ end
package/src/index.tsx CHANGED
@@ -1 +1,2 @@
1
- export { default as ErxesSDK } from './App';
1
+ export { ErxesNativeIOS } from './nativeIos';
2
+ export type { NativeIOSConfig, NativeIOSUser } from './nativeIos';
@@ -0,0 +1,74 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+
3
+ type NativeIOSConfig = {
4
+ integrationId: string;
5
+ endpoint?: string;
6
+ serverUrl?: string;
7
+ subDomain?: string;
8
+ cachedCustomerId?: string;
9
+ };
10
+
11
+ type NativeIOSUser = {
12
+ email?: string;
13
+ phone?: string;
14
+ name?: string;
15
+ customData?: Record<string, string | number | boolean | null | undefined>;
16
+ };
17
+
18
+ type NativeIOSModule = {
19
+ configure(options: NativeIOSConfig): Promise<void>;
20
+ setUser(options: NativeIOSUser): Promise<void>;
21
+ clearUser(): Promise<void>;
22
+ showMessenger(): Promise<void>;
23
+ showLauncher(): Promise<void>;
24
+ hideLauncher(): Promise<void>;
25
+ };
26
+
27
+ const LINKING_ERROR =
28
+ "The rn-erxes-sdk native iOS module is not linked. Run `pod install` in your app's ios directory and rebuild the app.";
29
+
30
+ const nativeModule = NativeModules.RnErxesSdk as NativeIOSModule | undefined;
31
+
32
+ function getNativeModule(): NativeIOSModule {
33
+ if (Platform.OS !== 'ios') {
34
+ throw new Error('Erxes native messenger is only available on iOS.');
35
+ }
36
+
37
+ if (!nativeModule) {
38
+ throw new Error(LINKING_ERROR);
39
+ }
40
+
41
+ return nativeModule;
42
+ }
43
+
44
+ export const ErxesNativeIOS = {
45
+ configure(options: NativeIOSConfig) {
46
+ return getNativeModule().configure(options);
47
+ },
48
+ setUser(options: NativeIOSUser) {
49
+ const customData = Object.fromEntries(
50
+ Object.entries(options.customData ?? {})
51
+ .filter(([, value]) => value !== null && value !== undefined)
52
+ .map(([key, value]) => [key, String(value)])
53
+ );
54
+
55
+ return getNativeModule().setUser({
56
+ ...options,
57
+ customData,
58
+ });
59
+ },
60
+ clearUser() {
61
+ return getNativeModule().clearUser();
62
+ },
63
+ showMessenger() {
64
+ return getNativeModule().showMessenger();
65
+ },
66
+ showLauncher() {
67
+ return getNativeModule().showLauncher();
68
+ },
69
+ hideLauncher() {
70
+ return getNativeModule().hideLauncher();
71
+ },
72
+ };
73
+
74
+ export type { NativeIOSConfig, NativeIOSUser };