-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fix] #371 전화 수신, 발신 시 소리 재생 오류 해결 #374
Changes from 4 commits
1d17bad
80c3e05
3870872
809795a
0723f0b
06d535f
18c3124
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
// | ||
|
||
import SwiftUI | ||
import Combine | ||
import AVFoundation | ||
|
||
class SoundManager { | ||
|
@@ -17,6 +18,8 @@ class SoundManager { | |
private let audioSession = AVAudioSession.sharedInstance() | ||
private var soundType: SoundType | ||
|
||
private var publisher: PassthroughSubject<Bool, Never> = .init() | ||
|
||
init?(appState: AppState) { | ||
self.appState = appState | ||
self.soundType = .beep | ||
|
@@ -40,15 +43,40 @@ class SoundManager { | |
self.engine.connect(dummyNode, to: self.engine.mainMixerNode, format: nil) | ||
|
||
// 엔진 시작 | ||
do { | ||
try engine.start() | ||
} catch { | ||
print("SoundManager: 오디오 엔진 시작 중 에러 발생 - \(error)") | ||
return nil | ||
} | ||
self.audioEngineStart() | ||
|
||
// 더미 노드 분리 | ||
self.engine.detach(dummyNode) | ||
|
||
// 전화 송/수신 시 interrupt 여부를 감지를 위한 notificationCenter 생성 | ||
self.setupNotifications() | ||
} | ||
|
||
@objc func handleInterruption(notification: Notification) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 메서드는 private으로 설정하지 않으신 이유가 궁금합니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아뇽,, 마지막에 private 체크했는데 objc가 앞에 있어서 당연히 뒤에 달려있다고 생각했나봅니다~ 수정해서 올리겠습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0723f0b 해당 커밋을 통해서 수정해두었습니다. |
||
guard let userInfo = notification.userInfo, | ||
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt, | ||
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else { | ||
return | ||
} | ||
switch type { | ||
case .began: | ||
self.publisher.send(true) | ||
self.engine.stop() | ||
|
||
case .ended: | ||
self.audioEngineStart() | ||
self.publisher.send(false) | ||
default: () | ||
} | ||
} | ||
|
||
private func setupNotifications() { | ||
let callInterruptNotificationCenter = NotificationCenter.default | ||
callInterruptNotificationCenter.addObserver(self, | ||
selector: #selector(handleInterruption), | ||
name: AVAudioSession.interruptionNotification, | ||
object: self.audioSession | ||
) | ||
} | ||
|
||
private func configureSoundPlayers(weak: String, medium: String, strong: String) throws { | ||
|
@@ -85,6 +113,21 @@ class SoundManager { | |
|
||
extension SoundManager: PlaySoundInterface { | ||
|
||
var callInterruptPublisher: AnyPublisher<Bool, Never> { | ||
publisher.eraseToAnyPublisher() | ||
} | ||
|
||
func audioEngineStart() { | ||
self.engine.stop() | ||
if !self.engine.isRunning { | ||
do { | ||
try self.engine.start() | ||
} catch { | ||
print("오디오 엔진 시작 및 재시작 실패: \(error.localizedDescription)") | ||
} | ||
} | ||
} | ||
|
||
func beep(_ accent: Accent) { | ||
|
||
guard let buffer = self.audioBuffers[accent] else { return } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bool값을 == true 인지 검증하는게 조금 어색해 보입니다
isCalling 같이 자체적으로 Bool값을 암시하는 변수명으로 대체하는게 어떨가요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
받는 값이 false일때 (전화가 끊겼을때) 아무 일도 하지 않는다고 하면
Bool값 대신 Void 타입으로 이벤트 발생만 전달하는 방안도 있을것 같습니다.
전화가 올때 재생이 멈추고 유저가 전화를 끊고 다시 재생을 눌러야 하는 방식으로 구현될것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
임시변수를 만들어도 해당 코드 내부에서 사용처가 없기 때문에 안만드는 것이 더 적합하다고 생각합니다. 방식은 말씀하신 것처럼 현재 전화 오면 재생이 멈추고 전화를 끊고 유저가 다시 재생을 누르는 식으로 구현되어 있습니다.
처리 방식을 변수로 처리하기보다 callInterrupt ? self.stop : nil 로 수정하는게 더 나을 것 같고,
이벤트 발생 여부만 전달하는 것이 가장 좋을 것 같습니다. 이벤트 여부 전달 방식으로 바꿔도 괜찮을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MetronomeOnOffUseCase의 tickPublisher가 Void 타입 Publisher로 구현되어 있습니다
참고가 되면 좋겠네여
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@YunKi-H 수정했습니다~ 확인 부탁드리며, 추가적으로 피드백 주실 부분이 있을지 확인 후 머지하겠습니다!