Skip to content

Commit 00a50c3

Browse files
committed
ios: change category to solo ambient
1. if we use Playback, it can supports background playing (starting from foreground), but it would not obey Ring/Silent switch. make sure you have enabled 'audio' tag ( or 'voip' tag ) at XCode -> Capabilities -> BackgroundMode 2. if we use SoloAmbient, it would obey Ring/Silent switch in the foreground, but does not support background playing, thus, then you should play ringtone again via local notification after back to home during a ring session. we prefer the second approach by default, since most of users doesn't want to be interrupted by a ringtone if Silent mode is on. if you doesn't care about Silent Switch, just pass 'playback' as a hint to the third argument when you call startRingtone().
1 parent 923d401 commit 00a50c3

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

index.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,17 @@ class InCallManager {
6060
_InCallManager.setMicrophoneMute(enable);
6161
}
6262

63-
startRingtone(ringtone, vibrate=false) {
63+
startRingtone(ringtone, vibrate, ios_category) {
6464
ringtone = (typeof ringtone === 'string') ? ringtone : "_DEFAULT_";
65-
_InCallManager.startRingtone(ringtone);
65+
vibrate = (vibrate === true) ? true : false;
66+
ios_category = (ios_category === 'playback') ? 'playback' : "default";
67+
68+
if (Platform.OS === 'android') {
69+
_InCallManager.startRingtone(ringtone);
70+
} else {
71+
_InCallManager.startRingtone(ringtone, ios_category);
72+
}
73+
6674
this.vibrate = vibrate;
6775
if (this.vibrate) {
6876
if (Platform.OS === 'android') {

ios/RNInCallManager/RNInCallManager.swift

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
4545
var audioSessionMediaServicesWereResetObserver: NSObjectProtocol?
4646
var audioSessionSilenceSecondaryAudioHintObserver: NSObjectProtocol?
4747

48-
var defaultAudioMode: String = AVAudioSessionModeVoiceChat
49-
var defaultAudioCategory: String = AVAudioSessionCategoryPlayAndRecord
48+
var incallAudioMode: String = AVAudioSessionModeVoiceChat
49+
var incallAudioCategory: String = AVAudioSessionCategoryPlayAndRecord
5050
var origAudioCategory: String!
5151
var origAudioMode: String!
5252
var audioSessionInitialized: Bool = false
@@ -55,7 +55,12 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
5555
var recordPermission: String!
5656
var cameraPermission: String!
5757
var media: String = "audio"
58-
58+
59+
// --- AVAudioSessionCategoryOptionAllowBluetooth:
60+
// --- Valid only if the audio session category is AVAudioSessionCategoryPlayAndRecord or AVAudioSessionCategoryRecord.
61+
// --- Using VoiceChat/VideoChat mode has the side effect of enabling the AVAudioSessionCategoryOptionAllowBluetooth category option.
62+
// --- So basically, we don't have to add AllowBluetooth options by hand.
63+
5964
//@objc func initWithBridge(_bridge: RCTBridge) {
6065
//self.bridge = _bridge
6166
override init() {
@@ -80,17 +85,17 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
8085

8186
// --- auto is always true on ios
8287
if self.media == "video" {
83-
self.defaultAudioMode = AVAudioSessionModeVideoChat
88+
self.incallAudioMode = AVAudioSessionModeVideoChat
8489
} else {
85-
self.defaultAudioMode = AVAudioSessionModeVoiceChat
90+
self.incallAudioMode = AVAudioSessionModeVoiceChat
8691
}
87-
NSLog("RNInCallManager.start() start InCallManager. media=\(self.media), type=\(self.media), mode=\(self.defaultAudioMode)")
92+
NSLog("RNInCallManager.start() start InCallManager. media=\(self.media), type=\(self.media), mode=\(self.incallAudioMode)")
8893
self.storeOriginalAudioSetup()
8994
self.forceSpeakerOn = 0;
9095
self.startAudioSessionNotification()
91-
//self.audioSessionSetCategory(self.defaultAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
92-
self.audioSessionSetCategory(self.defaultAudioCategory, nil, #function)
93-
self.audioSessionSetMode(self.defaultAudioMode, #function)
96+
//self.audioSessionSetCategory(self.incallAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
97+
self.audioSessionSetCategory(self.incallAudioCategory, nil, #function)
98+
self.audioSessionSetMode(self.incallAudioMode, #function)
9499
self.audioSessionSetActive(true, nil, #function)
95100
if !(ringbackUriType ?? "").isEmpty {
96101
NSLog("RNInCallManager.start() play ringback first. type=\(ringbackUriType)")
@@ -551,9 +556,9 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
551556
self.mRingback.numberOfLoops = -1 // you need to stop it explicitly
552557
self.mRingback.prepareToPlay()
553558

554-
//self.audioSessionSetCategory(self.defaultAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
555-
self.audioSessionSetCategory(self.defaultAudioCategory, nil, #function)
556-
self.audioSessionSetMode(self.defaultAudioMode, #function)
559+
//self.audioSessionSetCategory(self.incallAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
560+
self.audioSessionSetCategory(self.incallAudioCategory, nil, #function)
561+
self.audioSessionSetMode(self.incallAudioMode, #function)
557562
self.mRingback.play()
558563
} catch let err {
559564
NSLog("RNInCallManager.startRingback(): caught error=\(err)")
@@ -597,9 +602,9 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
597602
self.mBusytone.numberOfLoops = 0 // it's part of start(), will stop at stop()
598603
self.mBusytone.prepareToPlay()
599604

600-
//self.audioSessionSetCategory(self.defaultAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
601-
self.audioSessionSetCategory(self.defaultAudioCategory, nil, #function)
602-
self.audioSessionSetMode(self.defaultAudioMode, #function)
605+
//self.audioSessionSetCategory(self.incallAudioCategory, [.DefaultToSpeaker, .AllowBluetooth], #function)
606+
self.audioSessionSetCategory(self.incallAudioCategory, nil, #function)
607+
self.audioSessionSetMode(self.incallAudioMode, #function)
603608
self.mBusytone.play()
604609
} catch let err {
605610
NSLog("RNInCallManager.startBusytone(): caught error=\(err)")
@@ -617,7 +622,7 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
617622
}
618623

619624
// --- ringtoneUriType May be empty
620-
@objc func startRingtone(ringtoneUriType: String) -> Void {
625+
@objc func startRingtone(ringtoneUriType: String, ringtoneCategory: String) -> Void {
621626
// you may rejected by apple when publish app if you use system sound instead of bundled sound.
622627
NSLog("RNInCallManager.startRingtone(): type=\(ringtoneUriType)")
623628
do {
@@ -642,10 +647,19 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
642647
self.mRingtone.numberOfLoops = -1 // you need to stop it explicitly
643648
self.mRingtone.prepareToPlay()
644649

645-
// --- we must use playback to support background playing.
646-
// --- make sure you have enabled 'audio' tag ( or 'voip' tag ) at XCode -> Capabilities -> BackgroundMode
650+
// --- 1. if we use Playback, it can supports background playing (starting from foreground), but it would not obey Ring/Silent switch.
651+
// --- make sure you have enabled 'audio' tag ( or 'voip' tag ) at XCode -> Capabilities -> BackgroundMode
652+
// --- 2. if we use SoloAmbient, it would obey Ring/Silent switch in the foreground, but does not support background playing,
653+
// --- thus, then you should play ringtone again via local notification after back to home during a ring session.
654+
655+
// we prefer 2. by default, since most of users doesn't want to interrupted by a ringtone if Silent mode is on.
656+
647657
//self.audioSessionSetCategory(AVAudioSessionCategoryPlayback, [.DuckOthers], #function)
648-
self.audioSessionSetCategory(AVAudioSessionCategoryPlayback, nil, #function)
658+
if ringtoneCategory == "playback" {
659+
self.audioSessionSetCategory(AVAudioSessionCategoryPlayback, nil, #function)
660+
} else {
661+
self.audioSessionSetCategory(AVAudioSessionCategorySoloAmbient, nil, #function)
662+
}
649663
self.audioSessionSetMode(AVAudioSessionModeDefault, #function)
650664
//self.audioSessionSetActive(true, nil, #function)
651665
self.mRingtone.play()

ios/RNInCallManager/RNInCallManagerBridge.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ @interface RCT_EXTERN_REMAP_MODULE(InCallManager, RNInCallManager, NSObject)
1818
RCT_EXTERN_METHOD(setForceSpeakerphoneOn:(int)flag)
1919
RCT_EXTERN_METHOD(setMicrophoneMute:(BOOL)enable)
2020
RCT_EXTERN_METHOD(stopRingback)
21-
RCT_EXTERN_METHOD(startRingtone:(NSString *)ringtoneUriType)
21+
RCT_EXTERN_METHOD(startRingtone:(NSString *)ringtoneUriType ringtoneCategory:(NSString *)ringtoneCategory)
2222
RCT_EXTERN_METHOD(stopRingtone)
2323
RCT_EXTERN_METHOD(checkRecordPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
2424
RCT_EXTERN_METHOD(requestRecordPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)

0 commit comments

Comments
 (0)