@ -12,27 +12,34 @@ struct AudioSource: Hashable {
let image : UIImage
let image : UIImage
let localizedName : String
let localizedName : String
let portDescription : AVAudioSessionPortDescription ?
let portDescription : AVAudioSessionPortDescription ?
// T h e b u i l t i n l o u d s p e a k e r / a k a s p e a k e r p h o n e
let isBuiltInSpeaker : Bool
let isBuiltInSpeaker : Bool
init ( localizedName : String , image : UIImage , isBuiltInSpeaker : Bool , portDescription : AVAudioSessionPortDescription ? = nil ) {
// T h e b u i l d i n q u i e t s p e a k e r , a k a t h e n o r m a l p h o n e h a n d s e t r e c e i v e r e a r p i e c e
let isBuiltInEarPiece : Bool
init ( localizedName : String , image : UIImage , isBuiltInSpeaker : Bool , isBuiltInEarPiece : Bool , portDescription : AVAudioSessionPortDescription ? = nil ) {
self . localizedName = localizedName
self . localizedName = localizedName
self . image = image
self . image = image
self . isBuiltInSpeaker = isBuiltInSpeaker
self . isBuiltInSpeaker = isBuiltInSpeaker
self . isBuiltInEarPiece = isBuiltInEarPiece
self . portDescription = portDescription
self . portDescription = portDescription
}
}
init ( portDescription : AVAudioSessionPortDescription ) {
init ( portDescription : AVAudioSessionPortDescription ) {
let isBuiltInEarPiece = portDescription . portType = = AVAudioSessionPortBuiltInMic
// p o r t D e s c r i p t i o n . p o r t N a m e w o r k s w e l l f o r B T l i n k e d d e v i c e s , b u t i f w e a r e u s i n g
// p o r t D e s c r i p t i o n . p o r t N a m e w o r k s w e l l f o r B T l i n k e d d e v i c e s , b u t i f w e a r e u s i n g
// t h e b u i l t i n m i c , w e h a v e " i P h o n e M i c r o p h o n e " w h i c h i s a l i t t l e a w k w a r d .
// t h e b u i l t i n m i c , w e h a v e " i P h o n e M i c r o p h o n e " w h i c h i s a l i t t l e a w k w a r d .
// I n t h a t c a s e , i n s t e a d w e p r e f e r j u s t t h e m o d e l n a m e e . g . " i P h o n e " o r " i P a d "
// I n t h a t c a s e , i n s t e a d w e p r e f e r j u s t t h e m o d e l n a m e e . g . " i P h o n e " o r " i P a d "
let localizedName = portDescription . portType = = AVAudioSessionPortBuiltInMic ?
let localizedName = isBuiltInEarPiece ? UIDevice . current . localizedModel : portDescription . portName
UIDevice . current . localizedModel :
portDescription . portName
self . init ( localizedName : localizedName ,
self . init ( localizedName : localizedName ,
image : # imageLiteral ( resourceName : " button_phone_white " ) , // T O D O
image : # imageLiteral ( resourceName : " button_phone_white " ) , // T O D O
isBuiltInSpeaker : false ,
isBuiltInSpeaker : false ,
isBuiltInEarPiece : isBuiltInEarPiece ,
portDescription : portDescription )
portDescription : portDescription )
}
}
@ -40,7 +47,8 @@ struct AudioSource: Hashable {
static var builtInSpeaker : AudioSource {
static var builtInSpeaker : AudioSource {
return self . init ( localizedName : NSLocalizedString ( " AUDIO_ROUTE_BUILT_IN_SPEAKER " , comment : " action sheet button title to enable built in speaker during a call " ) ,
return self . init ( localizedName : NSLocalizedString ( " AUDIO_ROUTE_BUILT_IN_SPEAKER " , comment : " action sheet button title to enable built in speaker during a call " ) ,
image : # imageLiteral ( resourceName : " button_phone_white " ) , // T O D O
image : # imageLiteral ( resourceName : " button_phone_white " ) , // T O D O
isBuiltInSpeaker : true )
isBuiltInSpeaker : true ,
isBuiltInEarPiece : false )
}
}
// MARK: H a s h a b l e
// MARK: H a s h a b l e
@ -168,6 +176,13 @@ struct AudioSource: Hashable {
return
return
}
}
// D i s a l l o w b l u e t o o t h w h e n u s e r h a s e x p l i c i t l y c h o s e n t h e b u i l t i n r e c e i v e r .
// I ' m a c t u a l l y n o t s u r e w h y t h i s i s r e q u i r e d - i t s e e m s l i k e w e s h o u l d j u s t b e a b l e
// t o s e t P r e f e r r e d I n p u t t o c a l l . a u d i o S o u r c e . p o r t D e s c r i p t i o n i n t h i s c a s e ,
// b u t i n p r a c t i c e I ' m s e e i n g t h e c a l l r e v e r t t o t h e b l u e t o o t h h e a d s e t .
// P r e s u m a b l y s o m e t h i n g e l s e ( i n W e b R T C ? ) i s t o u c h i n g o u r s h a r e d A u d i o S e s s i o n .
let options : AVAudioSessionCategoryOptions = call . audioSource ? . isBuiltInEarPiece = = true ? [ ] : [ . allowBluetooth ]
if call . state = = . localRinging {
if call . state = = . localRinging {
// S o l o A m b i e n t p l a y s t h r o u g h s p e a k e r , b u t r e s p e c t s s i l e n t s w i t c h
// S o l o A m b i e n t p l a y s t h r o u g h s p e a k e r , b u t r e s p e c t s s i l e n t s w i t c h
setAudioSession ( category : AVAudioSessionCategorySoloAmbient ,
setAudioSession ( category : AVAudioSessionCategorySoloAmbient ,
@ -179,7 +194,7 @@ struct AudioSource: Hashable {
// d o e s n o t i n c l u d e m y l i n k e d b l u e t o o t h d e v i c e
// d o e s n o t i n c l u d e m y l i n k e d b l u e t o o t h d e v i c e
setAudioSession ( category : AVAudioSessionCategoryPlayAndRecord ,
setAudioSession ( category : AVAudioSessionCategoryPlayAndRecord ,
mode : AVAudioSessionModeVideoChat ,
mode : AVAudioSessionModeVideoChat ,
options : [ . allowBluetooth ] )
options : options )
} else {
} else {
// A p p l e D o c s s a y t h a t s e t t i n g m o d e t o A V A u d i o S e s s i o n M o d e V o i c e C h a t h a s t h e
// A p p l e D o c s s a y t h a t s e t t i n g m o d e t o A V A u d i o S e s s i o n M o d e V o i c e C h a t h a s t h e
// s i d e e f f e c t o f s e t t i n g o p t i o n s : . a l l o w B l u e t o o t h , w h e n I r e m o v e t h e ( s e e m i n g l y u n n e c e s s a r y )
// s i d e e f f e c t o f s e t t i n g o p t i o n s : . a l l o w B l u e t o o t h , w h e n I r e m o v e t h e ( s e e m i n g l y u n n e c e s s a r y )
@ -187,7 +202,7 @@ struct AudioSource: Hashable {
// d o e s n o t i n c l u d e m y l i n k e d b l u e t o o t h d e v i c e
// d o e s n o t i n c l u d e m y l i n k e d b l u e t o o t h d e v i c e
setAudioSession ( category : AVAudioSessionCategoryPlayAndRecord ,
setAudioSession ( category : AVAudioSessionCategoryPlayAndRecord ,
mode : AVAudioSessionModeVoiceChat ,
mode : AVAudioSessionModeVoiceChat ,
options : [ . allowBluetooth ] )
options : options )
}
}
let session = AVAudioSession . sharedInstance ( )
let session = AVAudioSession . sharedInstance ( )