@nativetalkcommunications/react-native-call-sdk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -224
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @nativetalkcommunications/react-native-call-sdk
|
|
2
2
|
|
|
3
|
-
> Plug-and-play SIP / VoIP calling for React Native
|
|
3
|
+
> Plug-and-play SIP / VoIP calling for React Native.
|
|
4
4
|
>
|
|
5
5
|
> Drop-in `<CallProvider>`, a `useCall()` hook, optional UI screens — and a
|
|
6
6
|
> native Android + iOS layer that handles backgrounding, foreground services,
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
| Feature | Notes |
|
|
14
14
|
|---|---|
|
|
15
15
|
| **Plug-and-play** | One provider, one hook. No coupling to your auth, navigation, or HTTP client. |
|
|
16
|
-
| **Cross-platform** | Android (Linphone SDK 5.x) and iOS (Linphone 5.x + CallKit-ready). |
|
|
17
16
|
| **Backgrounded calls** | Android foreground service keeps the registration warm. iOS supports VoIP push. |
|
|
18
17
|
| **Bundled UI** | Optional `<Dialer />`, `<IncomingCallView />`, `<OutgoingCallView />`. Use them or roll your own. |
|
|
19
18
|
| **Typed** | First-class TypeScript types throughout. |
|
|
@@ -26,7 +25,6 @@
|
|
|
26
25
|
- React Native ≥ 0.73
|
|
27
26
|
- iOS ≥ 13.0
|
|
28
27
|
- Android `minSdkVersion` ≥ 24 (Android 7.0)
|
|
29
|
-
- Linphone SDK 5.4.x (Android pulled automatically via Maven; iOS xcframeworks downloaded automatically on first `pod install`)
|
|
30
28
|
- **React Native < 0.82:** set `newArchEnabled=false` in `android/gradle.properties`. React Native ≥ 0.82 runs New Architecture by default and the SDK works via the interop layer — the flag is not needed.
|
|
31
29
|
|
|
32
30
|
---
|
|
@@ -67,12 +65,6 @@ If your app uses Expo, the config plugin handles all native configuration automa
|
|
|
67
65
|
npx expo prebuild
|
|
68
66
|
```
|
|
69
67
|
|
|
70
|
-
This automatically configures:
|
|
71
|
-
- **Android** — adds the Linphone Maven repository to `android/build.gradle`
|
|
72
|
-
- **iOS** — adds `NSMicrophoneUsageDescription` and `UIBackgroundModes` to `Info.plist`, and adds the `pod 'linphonesw'` line to the `Podfile`
|
|
73
|
-
|
|
74
|
-
Prebuild also runs `pod install` automatically. On the first run, the linphonesw pod downloads the Linphone xcframeworks (~90 seconds, one-time per machine). No SPM step, no manual setup.
|
|
75
|
-
|
|
76
68
|
---
|
|
77
69
|
|
|
78
70
|
### Installing from a local path (development only)
|
|
@@ -161,226 +153,153 @@ Same as the npm install path — the plugin configures Android and iOS automatic
|
|
|
161
153
|
|
|
162
154
|
---
|
|
163
155
|
|
|
164
|
-
##
|
|
165
|
-
|
|
166
|
-
If you are **not** using Expo, follow the Android and iOS setup sections below manually.
|
|
167
|
-
|
|
168
|
-
### Local installs only — update Metro config
|
|
169
|
-
|
|
170
|
-
**Skip this step for published npm installs.** If installing from a local path (e.g. `"file:../nativetalk-call-sdk"`), merge the following into your `metro.config.js`. If you already have a `watchFolders`, `extraNodeModules`, or `nodeModulesPaths` config, add the SDK entries to your existing arrays/objects rather than replacing them.
|
|
171
|
-
|
|
172
|
-
```js
|
|
173
|
-
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
|
|
174
|
-
const path = require('path');
|
|
175
|
-
|
|
176
|
-
const sdkPath = path.resolve(__dirname, '../nativetalk-call-sdk'); // adjust path as needed
|
|
177
|
-
|
|
178
|
-
const sdkConfig = {
|
|
179
|
-
watchFolders: [sdkPath],
|
|
180
|
-
resolver: {
|
|
181
|
-
unstable_enableSymlinks: true,
|
|
182
|
-
extraNodeModules: {
|
|
183
|
-
'@nativetalkcommunications/react-native-call-sdk': sdkPath,
|
|
184
|
-
'react': path.resolve(__dirname, 'node_modules/react'),
|
|
185
|
-
'react-native': path.resolve(__dirname, 'node_modules/react-native'),
|
|
186
|
-
},
|
|
187
|
-
nodeModulesPaths: [
|
|
188
|
-
path.resolve(__dirname, 'node_modules'),
|
|
189
|
-
path.resolve(sdkPath, 'node_modules'),
|
|
190
|
-
],
|
|
191
|
-
},
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
module.exports = mergeConfig(getDefaultConfig(__dirname), sdkConfig);
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
> **If your metro.config.js already calls `mergeConfig`**, pass `sdkConfig` as an additional argument: `mergeConfig(getDefaultConfig(__dirname), yourExistingConfig, sdkConfig)`.
|
|
198
|
-
|
|
199
|
-
### Local installs only — remove duplicate react/react-native
|
|
200
|
-
|
|
201
|
-
**Skip this step for published npm installs.** Check if duplicates exist and delete them:
|
|
202
|
-
|
|
203
|
-
```bash
|
|
204
|
-
ls ../nativetalk-call-sdk/node_modules | grep react # check first
|
|
205
|
-
rm -rf ../nativetalk-call-sdk/node_modules/react
|
|
206
|
-
rm -rf ../nativetalk-call-sdk/node_modules/react-native
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## Android setup
|
|
212
|
-
|
|
213
|
-
### 1. Add the Linphone Maven repository
|
|
214
|
-
|
|
215
|
-
The Linphone SDK is not published to Maven Central. You need to add their repository to `android/settings.gradle`.
|
|
156
|
+
## Quick start
|
|
216
157
|
|
|
217
|
-
|
|
158
|
+
```tsx
|
|
159
|
+
import React, { useState } from 'react';
|
|
160
|
+
import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert } from 'react-native';
|
|
161
|
+
import { CallProvider, useCall } from '@nativetalkcommunications/react-native-call-sdk';
|
|
162
|
+
import { Dialer } from '@nativetalkcommunications/react-native-call-sdk/ui';
|
|
218
163
|
|
|
219
|
-
|
|
164
|
+
function LoginScreen({ onLogin }) {
|
|
165
|
+
const [username, setUsername] = useState('100');
|
|
166
|
+
const [password, setPassword] = useState('secret');
|
|
167
|
+
const [domain, setDomain] = useState('pbx.example.com');
|
|
168
|
+
const [transport, setTransport] = useState('tcp');
|
|
220
169
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
repositories {
|
|
226
|
-
google()
|
|
227
|
-
mavenCentral()
|
|
228
|
-
maven { url "https://www.jitpack.io" }
|
|
229
|
-
maven {
|
|
230
|
-
name = "linphone.org maven repository"
|
|
231
|
-
url = uri("https://download.linphone.org/maven_repository")
|
|
232
|
-
content {
|
|
233
|
-
includeGroup("org.linphone")
|
|
234
|
-
}
|
|
235
|
-
}
|
|
170
|
+
const handleLogin = () => {
|
|
171
|
+
if (!username || !password || !domain) {
|
|
172
|
+
Alert.alert('Error', 'Please fill in all fields');
|
|
173
|
+
return;
|
|
236
174
|
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
> **Important:** `repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)` means only repositories listed in this block are used — adding repos elsewhere (e.g. `android/build.gradle`) will be silently ignored. Make sure `google()` and `mavenCentral()` are included here too.
|
|
241
|
-
|
|
242
|
-
Without the Linphone repo your build will fail with:
|
|
243
|
-
```
|
|
244
|
-
Could not find org.linphone:linphone-sdk-android:5.4.x.
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
> **Wrong URL**: The older Linphone URL (`linphone.org/maven/repository`) is dead. Use `download.linphone.org/maven_repository` as shown above.
|
|
248
|
-
|
|
249
|
-
### 2. Disable New Architecture
|
|
250
|
-
|
|
251
|
-
The SDK uses the Old Architecture (NativeModules/NativeEventEmitter) bridge. Open `android/gradle.properties` and set:
|
|
252
|
-
|
|
253
|
-
```properties
|
|
254
|
-
newArchEnabled=false
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
If you previously had this set to `true`, you must do a clean reinstall:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
# Uninstall the old APK from the device first
|
|
261
|
-
adb uninstall com.yourapp
|
|
262
|
-
|
|
263
|
-
# Then full clean rebuild
|
|
264
|
-
cd android && ./gradlew clean && cd ..
|
|
265
|
-
npx react-native run-android
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Without the clean uninstall, the old New Architecture binary might remain on-device and could crash with:
|
|
269
|
-
```
|
|
270
|
-
PlatformConstants could not be found. Verify that it is available as a TurboModule.
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### 3. Autolink
|
|
274
|
-
|
|
275
|
-
No `MainApplication` edits needed — the SDK autolinks.
|
|
276
|
-
|
|
277
|
-
### 4. Runtime permissions
|
|
175
|
+
onLogin({ username, password, domain, transport });
|
|
176
|
+
};
|
|
278
177
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
cd ios && pod install
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
On the first install, the pod automatically downloads the Linphone xcframeworks (~90 seconds). This is a one-time operation — CocoaPods caches the result so subsequent installs are instant.
|
|
319
|
-
|
|
320
|
-
> **No SPM step required.** The old workflow of adding the Linphone Swift Package in Xcode is no longer needed.
|
|
321
|
-
|
|
322
|
-
### 3. Info.plist
|
|
323
|
-
|
|
324
|
-
Add to `ios/YourApp/Info.plist`:
|
|
325
|
-
|
|
326
|
-
```xml
|
|
327
|
-
<key>NSMicrophoneUsageDescription</key>
|
|
328
|
-
<string>Microphone access is required for calls.</string>
|
|
329
|
-
|
|
330
|
-
<key>UIBackgroundModes</key>
|
|
331
|
-
<array>
|
|
332
|
-
<string>audio</string>
|
|
333
|
-
<string>voip</string>
|
|
334
|
-
</array>
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
Without `NSMicrophoneUsageDescription` your app will crash when Linphone requests the mic. Without `UIBackgroundModes`, iOS will kill the SIP connection when your app is backgrounded.
|
|
338
|
-
|
|
339
|
-
### 4. Xcode capabilities
|
|
340
|
-
|
|
341
|
-
In Xcode → your target → **Signing & Capabilities**:
|
|
342
|
-
|
|
343
|
-
- Add **Background Modes** → tick **Audio, AirPlay and Picture in Picture** and **Voice over IP**
|
|
344
|
-
|
|
345
|
-
This mirrors the `UIBackgroundModes` in Info.plist — both are required.
|
|
346
|
-
|
|
347
|
-
### 5. Simulator vs real device
|
|
348
|
-
|
|
349
|
-
Registration and foreground calls work on the iOS Simulator. What does **not** work on the simulator is PushKit — VoIP push tokens are never delivered to simulators, so background/killed-app inbound calls won't work there. For testing push-driven inbound calls, use a real iPhone.
|
|
178
|
+
return (
|
|
179
|
+
<View style={styles.loginContainer}>
|
|
180
|
+
<Text style={styles.title}>SIP Credentials</Text>
|
|
181
|
+
<TextInput
|
|
182
|
+
style={styles.input}
|
|
183
|
+
placeholder="Username"
|
|
184
|
+
value={username}
|
|
185
|
+
onChangeText={setUsername}
|
|
186
|
+
/>
|
|
187
|
+
<TextInput
|
|
188
|
+
style={styles.input}
|
|
189
|
+
placeholder="Password"
|
|
190
|
+
value={password}
|
|
191
|
+
onChangeText={setPassword}
|
|
192
|
+
secureTextEntry
|
|
193
|
+
/>
|
|
194
|
+
<TextInput
|
|
195
|
+
style={styles.input}
|
|
196
|
+
placeholder="Domain"
|
|
197
|
+
value={domain}
|
|
198
|
+
onChangeText={setDomain}
|
|
199
|
+
/>
|
|
200
|
+
<TextInput
|
|
201
|
+
style={styles.input}
|
|
202
|
+
placeholder="Transport (tcp/udp)"
|
|
203
|
+
value={transport}
|
|
204
|
+
onChangeText={setTransport}
|
|
205
|
+
/>
|
|
206
|
+
<TouchableOpacity style={styles.button} onPress={handleLogin}>
|
|
207
|
+
<Text style={styles.buttonText}>Login</Text>
|
|
208
|
+
</TouchableOpacity>
|
|
209
|
+
</View>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
350
212
|
|
|
351
|
-
|
|
213
|
+
function DialerWithSignout({ onLogout }) {
|
|
214
|
+
const { isRegistered } = useCall();
|
|
352
215
|
|
|
353
|
-
|
|
216
|
+
return (
|
|
217
|
+
<View style={styles.dialerContainer}>
|
|
218
|
+
{isRegistered && (
|
|
219
|
+
<TouchableOpacity style={styles.signoutButton} onPress={onLogout}>
|
|
220
|
+
<Text style={styles.signoutText}>Sign Out</Text>
|
|
221
|
+
</TouchableOpacity>
|
|
222
|
+
)}
|
|
223
|
+
<Dialer />
|
|
224
|
+
</View>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
354
227
|
|
|
355
|
-
|
|
228
|
+
export default function App() {
|
|
229
|
+
const [config, setConfig] = useState(null);
|
|
356
230
|
|
|
357
|
-
|
|
231
|
+
const handleLogin = (credentials) => {
|
|
232
|
+
setConfig(credentials);
|
|
233
|
+
};
|
|
358
234
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
import { CallProvider, useCall } from '@nativetalkcommunications/react-native-call-sdk';
|
|
363
|
-
import { Dialer } from '@nativetalkcommunications/react-native-call-sdk/ui';
|
|
235
|
+
const handleLogout = () => {
|
|
236
|
+
setConfig(null);
|
|
237
|
+
};
|
|
364
238
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
domain: 'yourcompany.nativetalk.io', // must be a *.nativetalk.io domain
|
|
369
|
-
transport: 'tcp',
|
|
370
|
-
};
|
|
239
|
+
if (!config) {
|
|
240
|
+
return <LoginScreen onLogin={handleLogin} />;
|
|
241
|
+
}
|
|
371
242
|
|
|
372
|
-
export default function App() {
|
|
373
243
|
return (
|
|
374
244
|
<CallProvider
|
|
375
|
-
config={
|
|
245
|
+
config={config}
|
|
376
246
|
onIncomingCall={(info) => console.log('Incoming from', info.phone)}
|
|
377
247
|
onRegistrationStateChanged={(r) => console.log('SIP:', r.state)}
|
|
378
248
|
onError={(e) => Alert.alert('SDK Error', e.message)}
|
|
379
249
|
>
|
|
380
|
-
<
|
|
250
|
+
<DialerWithSignout onLogout={handleLogout} />
|
|
381
251
|
</CallProvider>
|
|
382
252
|
);
|
|
383
253
|
}
|
|
254
|
+
|
|
255
|
+
const styles = StyleSheet.create({
|
|
256
|
+
loginContainer: {
|
|
257
|
+
flex: 1,
|
|
258
|
+
padding: 16,
|
|
259
|
+
justifyContent: 'center',
|
|
260
|
+
},
|
|
261
|
+
dialerContainer: {
|
|
262
|
+
flex: 1,
|
|
263
|
+
},
|
|
264
|
+
title: {
|
|
265
|
+
fontSize: 24,
|
|
266
|
+
fontWeight: 'bold',
|
|
267
|
+
marginBottom: 24,
|
|
268
|
+
textAlign: 'center',
|
|
269
|
+
},
|
|
270
|
+
input: {
|
|
271
|
+
backgroundColor: '#fff',
|
|
272
|
+
borderRadius: 8,
|
|
273
|
+
paddingHorizontal: 12,
|
|
274
|
+
paddingVertical: 10,
|
|
275
|
+
marginBottom: 12,
|
|
276
|
+
borderWidth: 1,
|
|
277
|
+
borderColor: '#ddd',
|
|
278
|
+
},
|
|
279
|
+
button: {
|
|
280
|
+
backgroundColor: '#2196F3',
|
|
281
|
+
paddingVertical: 12,
|
|
282
|
+
borderRadius: 8,
|
|
283
|
+
alignItems: 'center',
|
|
284
|
+
},
|
|
285
|
+
buttonText: {
|
|
286
|
+
color: '#fff',
|
|
287
|
+
fontSize: 16,
|
|
288
|
+
fontWeight: '600',
|
|
289
|
+
},
|
|
290
|
+
signoutButton: {
|
|
291
|
+
backgroundColor: '#F44336',
|
|
292
|
+
paddingHorizontal: 16,
|
|
293
|
+
paddingVertical: 8,
|
|
294
|
+
borderRadius: 6,
|
|
295
|
+
alignItems: 'center',
|
|
296
|
+
margin: 12,
|
|
297
|
+
},
|
|
298
|
+
signoutText: {
|
|
299
|
+
color: '#fff',
|
|
300
|
+
fontSize: 14,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
384
303
|
```
|
|
385
304
|
|
|
386
305
|
**Error handling** — all SDK errors are surfaced through `onError`. The callback receives `{ code: string, message: string }`. Common codes:
|
|
@@ -417,27 +336,12 @@ function CallControls() {
|
|
|
417
336
|
|
|
418
337
|
---
|
|
419
338
|
|
|
420
|
-
## Common errors
|
|
421
|
-
|
|
422
|
-
| Error | Cause | Fix |
|
|
423
|
-
|---|---|---|
|
|
424
|
-
| `Could not find org.linphone:linphone-sdk-android` | Wrong or missing Maven repo | Add `download.linphone.org/maven_repository` to `android/build.gradle` in the `allprojects { repositories { } }` block |
|
|
425
|
-
| `PlatformConstants could not be found` | New Architecture enabled but SDK uses Old Arch | Set `newArchEnabled=false` in `gradle.properties`, uninstall APK, clean rebuild |
|
|
426
|
-
| `TurboModuleRegistry … was not found` | Duplicate react-native in SDK node_modules | Delete `nativetalk-call-sdk/node_modules/react` and `.../react-native` |
|
|
427
|
-
| `Unable to load script` | Metro not running after clean build | Start Metro separately (`npx react-native start`), then run the app |
|
|
428
|
-
| `No podspec found for linphonesw` | Podfile missing the `pod 'linphonesw'` line | Add `pod 'linphonesw', :path => '../node_modules/@nativetalkcommunications/react-native-call-sdk/linphonesw-pod'` to your Podfile |
|
|
429
|
-
| `'jni.h' file not found` | Linphone xcframeworks embedded directly in NativetalkCallSdk module | Ensure linphonesw is a separate pod — do not vendor the xcframeworks directly in NativetalkCallSdk |
|
|
430
|
-
| Inbound calls not received (Android emulator) | Emulator NAT — SIP server can't reach `10.0.2.15` | Test on a real Android device |
|
|
431
|
-
| Inbound calls not received (iOS) | App backgrounded without VoIP push | Wire up CallKit + PushKit; see `docs/push-notifications.md` |
|
|
432
|
-
|
|
433
|
-
---
|
|
434
|
-
|
|
435
339
|
## Documentation
|
|
436
340
|
|
|
437
341
|
| Topic | Where |
|
|
438
342
|
|---|---|
|
|
439
343
|
| **Android setup deep-dive** — services, channels, manifest, Maven repo | [docs/android-setup.md](docs/android-setup.md) |
|
|
440
|
-
| **iOS setup deep-dive** —
|
|
344
|
+
| **iOS setup deep-dive** — CallKit, PushKit | [docs/ios-setup.md](docs/ios-setup.md) |
|
|
441
345
|
| **Configuration** — every prop on `<CallProvider>` | [docs/configuration.md](docs/configuration.md) |
|
|
442
346
|
| **API reference** — every export, every type | [docs/api-reference.md](docs/api-reference.md) |
|
|
443
347
|
| **Bundled UI components** — props, theming, customization | [docs/ui-components.md](docs/ui-components.md) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nativetalkcommunications/react-native-call-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Plug-and-play SIP/VoIP calling SDK for React Native, powered by Linphone. Provides registration, dial, answer, hold, mute, speaker, DTMF, and call logs — plus optional UI components.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
],
|
|
63
63
|
"repository": {
|
|
64
64
|
"type": "git",
|
|
65
|
-
"url": "https://github.com/Tech4mation/nativetalk-call-sdk.git"
|
|
65
|
+
"url": "git+https://github.com/Tech4mation/nativetalk-call-sdk.git"
|
|
66
66
|
},
|
|
67
67
|
"license": "MIT",
|
|
68
68
|
"peerDependencies": {
|