rns-nativecall 0.8.5 → 0.8.7

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/ios/CallModule.m CHANGED
@@ -79,6 +79,7 @@ RCT_EXPORT_METHOD(displayIncomingCall:(NSString *)uuidString
79
79
 
80
80
  self.currentCallUUID = uuid;
81
81
 
82
+ // Pre-configure audio session
82
83
  AVAudioSession *session = [AVAudioSession sharedInstance];
83
84
  [session setCategory:AVAudioSessionCategoryPlayAndRecord
84
85
  mode:AVAudioSessionModeVoiceChat
@@ -98,17 +99,14 @@ RCT_EXPORT_METHOD(displayIncomingCall:(NSString *)uuidString
98
99
  }];
99
100
  }
100
101
 
101
- // Handles programmatic ending (e.g., via FCM "CANCEL")
102
102
  RCT_EXPORT_METHOD(reportRemoteEnded:(NSString *)uuidString reason:(NSInteger)reason) {
103
103
  NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidString];
104
104
  if (!uuid) return;
105
105
 
106
- // Report to CallKit that the remote user ended the call
107
106
  [self.provider reportCallWithUUID:uuid
108
107
  endedAtDate:[NSDate date]
109
108
  reason:(CXCallEndedReason)reason];
110
109
 
111
- // Clear local tracking
112
110
  if ([uuid isEqual:self.currentCallUUID]) {
113
111
  self.currentCallUUID = nil;
114
112
  self.pendingCallUuid = nil;
@@ -123,29 +121,38 @@ RCT_EXPORT_METHOD(endNativeCall:(NSString *)uuidString)
123
121
  // MARK: - CXProviderDelegate
124
122
 
125
123
  - (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
124
+ // 1. Force the Audio Session active immediately so the system hands off the hardware
126
125
  AVAudioSession *session = [AVAudioSession sharedInstance];
126
+ NSError *audioError = nil;
127
127
  [session setCategory:AVAudioSessionCategoryPlayAndRecord
128
128
  mode:AVAudioSessionModeVoiceChat
129
129
  options:AVAudioSessionCategoryOptionAllowBluetoothHFP | AVAudioSessionCategoryOptionDefaultToSpeaker
130
130
  error:nil];
131
- [session setActive:YES error:nil];
131
+ [session setActive:YES error:&audioError];
132
132
 
133
+ // 2. Fulfill the system action
133
134
  [action fulfill];
134
135
 
135
136
  NSString *uuidStr = [action.callUUID.UUIDString lowercaseString];
136
137
  self.pendingCallUuid = uuidStr;
137
138
 
138
- // Switch from system UI to App UI
139
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
139
+ // 3. Move to Main Queue for UI Handoff
140
+ dispatch_async(dispatch_get_main_queue(), ^{
141
+
142
+ // This is the trigger that "destroys" the CallKit UI without failing the call
143
+ // It tells iOS the call is being handled by another device/interface (the app)
140
144
  [self.provider reportCallWithUUID:action.callUUID
141
145
  endedAtDate:[NSDate date]
142
146
  reason:CXCallEndedReasonAnsweredElsewhere];
143
147
 
144
- dispatch_async(dispatch_get_main_queue(), ^{
145
- [[[UIApplication sharedApplication] keyWindow] makeKeyAndVisible];
146
- });
148
+ // Ensure the app window is visible/active
149
+ [[[UIApplication sharedApplication] keyWindow] makeKeyAndVisible];
147
150
 
151
+ // Notify React Native that the call is accepted
148
152
  [self sendEventWithName:@"onCallAccepted" body:@{@"callUuid": uuidStr}];
153
+
154
+ // Clear local tracking so displayIncomingCall can be used again
155
+ self.currentCallUUID = nil;
149
156
  });
150
157
  }
151
158
 
@@ -157,7 +164,7 @@ RCT_EXPORT_METHOD(endNativeCall:(NSString *)uuidString)
157
164
  }
158
165
 
159
166
  - (void)providerDidReset:(CXProvider *)provider {
160
- [[AVAudioSession sharedInstance] setActive:NO error:nil];
167
+ // Important: Do NOT deactivate audio if a call is transitioning to the app
161
168
  self.currentCallUUID = nil;
162
169
  self.pendingCallUuid = nil;
163
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "description": "High-performance React Native module for handling native VoIP call UI on Android and iOS.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -169,16 +169,16 @@ function withIosConfig(config, props = {}) {
169
169
  // Explicit check: only disable if strictly false
170
170
  const enableAudio = iosBackgroundAudio !== false;
171
171
 
172
- if (enableAudio) {
173
- if (!infoPlist.UIBackgroundModes.includes('audio')) {
174
- infoPlist.UIBackgroundModes.push('audio');
175
- }
176
- } else {
177
- infoPlist.UIBackgroundModes = infoPlist.UIBackgroundModes.filter(
178
- (mode) => mode !== 'audio'
179
- );
180
- console.log(`[rns-nativecall] 'audio' background mode removed.`);
181
- }
172
+ // if (enableAudio) {
173
+ // if (!infoPlist.UIBackgroundModes.includes('audio')) {
174
+ // infoPlist.UIBackgroundModes.push('audio');
175
+ // }
176
+ // } else {
177
+ // infoPlist.UIBackgroundModes = infoPlist.UIBackgroundModes.filter(
178
+ // (mode) => mode !== 'audio'
179
+ // );
180
+ // console.log(`[rns-nativecall] 'audio' background mode removed.`);
181
+ // }
182
182
 
183
183
  ['voip', 'remote-notification'].forEach(mode => {
184
184
  if (!infoPlist.UIBackgroundModes.includes(mode)) {