Skip to content

Conversation

@sangYuLv
Copy link
Collaborator

@sangYuLv sangYuLv commented Feb 5, 2026

🔗 연관된 이슈

📝 작업 내용

📌 요약

  • CameraPreview에서 리모트 기기 연결 끊김 감지 (워치 포함)

🔍 상세

  • 타이머 모드 선택 → 리모트 기기 끊겨도 반응 안 함
  • 리모트 모드 선택 → 리모트 기기 끊기면 모든 연결 정리

애플워치에서도 위 동작이 제대로 되는 것을 확인했습니다.

애플워치가 아닌 리모트 기기의 촬영 버튼 화면의 뒤로가기 버튼을 제거했습니다.

  • 버튼에서 뒤로 가면 연결 완료 화면인데, 이를 연결 끊김이라고 취급하지 않습니다.
  • 따라서 백버튼을 제거했고, 해당 화면에서 연결 끊기 기능이 필요하다면 버튼을 추가하고 이전 화면이 아니라 아예 초기화 하는 방법이 좋을 듯 합니다.

📸 영상 / 이미지

애플워치가 아닌 리모트 기기

remote.mov

애플워치

watch.mov

@sangYuLv sangYuLv self-assigned this Feb 5, 2026
@sangYuLv sangYuLv added 🐞 fix 버그 수정 🔨 refactor 코드 리팩토링 (기능 변화 없이 구조 개선, 불필요한 import 제거) labels Feb 5, 2026
Copy link
Collaborator

@YunDaeHyeon YunDaeHyeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📄 PR Code Review Report

🔍 Summary

이번 PR은 Apple Watch 연동 기능을 추가하고, 기기 연결 해제(disconnection) 로직을 개선하는 중요한 변경 사항을 포함하고 있습니다. 전반적으로 새로운 요구사항에 맞춰 의존성 주입을 정돈하고, 연결 상태 관리를 강화한 점이 긍정적입니다. 다만, 특정 연결 해제 시나리오에서 기존 코드의 잠재적인 오류가 새 로직과 결합하여 발생할 수 있는 주요 버그가 발견되었습니다. 이 부분을 해결하면 프로덕션 안정성을 크게 향상시킬 수 있습니다.

⚠️ Key Issues

  1. 미러링 기기 연결 해제 시 처리 오류 가능성 (Critical Bug):
    CameraPreviewStore에서 미러링 기기의 하트비트 타임아웃(mirroringHeartBeater.heartbeatTimeout)이 발생했을 때, self.browser.disconnect(useType: .remote)를 호출하는 로직이 발견되었습니다. heartbeatTimeout이 미러링 기기 자체의 연결 해제를 의미한다면, useType: .remote로 원격 제어기(예: 워치나 보조 리모트폰)만 연결 해제하는 것은 부적절합니다. 미러링 기기가 끊어졌다면, 메인 세션이 종료되어야 하며, handleDisconnection()과 같이 주 연결을 해제하는 방식으로 처리되어야 합니다. 현재 로직은 미러링 기기가 끊겼음에도 리모트 컨트롤러만 끊고 미러링 세션은 불완전한 상태로 남아있게 할 위험이 있습니다.

  2. isTimerModeSelected 플래그 관련 경합 조건 (Race Condition) 가능성:
    BrowserCommandManager에서 .selectedTimerMode 명령 수신 시 isTimerModeSelected 플래그를 true로 동기적으로 설정한 뒤 UI 업데이트를 비동기로 처리하여 워치 연결 해제 무시 로직의 경합 조건을 완화하려는 시도는 긍정적입니다. 그러나 네트워크 지연으로 인해 미러링 기기에서 워치 연결 해제 요청을 보내는 시점과 카메라 기기에서 isTimerModeSelected 플래그가 업데이트되는 시점 사이에 짧은 경합 조건 구간이 존재할 수 있습니다. 이로 인해 워치가 연결 해제되기 직전 타이머 모드가 선택되었음에도 불구하고, 카메라 기기에서 플래그가 업데이트되기 전에 워치 연결 해제 이벤트가 먼저 감지되어 예기치 않게 전체 연결이 끊길 가능성이 있습니다. 이는 분산 시스템에서 완전히 제거하기 어려운 문제이나, 인지하고 있어야 합니다.

🛠 Improvement Suggestions

  1. remoteType Optionality 명확화:
    ConnectionListConnectionCheckStore, CameraPreview 등으로 remoteType: DeviceType?이 전달되고 있습니다. remoteTypenil인 경우를 명시적으로 처리하는 코드 (guard let remoteType else { return } 등)를 추가하여 옵셔널 체이닝으로 인한 잠재적 오류를 방지하고, 해당 값이 필수적인 경우 초기화 실패 등 명확한 동작을 유도할 수 있습니다.

  2. Browser.disconnect()의 명확한 정의:
    Browser 클래스의 disconnect() 메서드가 useType 파라미터 없이 호출될 때, 정확히 어떤 연결(미러링, 리모트 등)을 해제하는지 문서화하거나, 명확한 네이밍으로 변경하여 오용을 방지하는 것이 좋습니다. 예를 들어 disconnectPrimaryMirroringDevice() 또는 disconnectAllDevices()와 같이 구체적인 이름을 사용하면 좋습니다.

✅ Positive Observations

  1. WatchConnectionManager 의존성 주입:
    WatchConnectionManagerRootView, Router, BrowsingView, ConnectionCheckStore, ConnectionCheckView, CameraPreviewStore 등 필요한 컴포넌트에 체계적으로 주입되고 있습니다. 이는 새로운 워치 기능의 아키텍처적 일관성을 유지하며 의존성 관리를 잘 수행한 좋은 사례입니다.

  2. 연결 해제 로직의 통합:
    CameraPreviewStore에서 handleDisconnection() 메서드를 도입하여 주 연결 해제 로직을 한 곳으로 통합한 점이 좋습니다. 이는 코드 중복을 줄이고, 향후 연결 해제 동작 변경 시 유지보수성을 높이는 데 기여합니다.

  3. ModeSelectionView 로직 개선:
    ModeSelectionView에서 noticeShootingMode 메서드의 시그니처가 isTimer: Bool로 변경되고, 모드 선택 시점에 명확하게 타이머/리모콘 모드를 구분하여 명령을 전송하도록 수정되었습니다. 이전에 포즈 추천과 같은 부가 선택에서 모드 명령을 잘못 전송할 수 있었던 잠재적인 로직 오류를 해결하고, 코드의 의도를 명확히 한 좋은 개선입니다.

  4. 명확한 상태명 변경:
    isMirroringDisconnectedisPrimaryDeviceDisconnected로 변경된 것은 미러링 기기 외에 워치와 같은 다른 주 연결 장치의 해제 상황까지 포괄하여 상태명의 추상화 및 명확성을 높였습니다.

@sangYuLv sangYuLv modified the milestone: WEEK05 Feb 5, 2026
@sangYuLv sangYuLv marked this pull request as ready for review February 5, 2026 07:48
@sangYuLv sangYuLv force-pushed the refactor/#292-fix-alert branch from 4c2398f to f33fbf0 Compare February 5, 2026 09:38
Base automatically changed from refactor/#292-fix-alert to develop February 5, 2026 09:41
Copy link
Collaborator

@YunDaeHyeon YunDaeHyeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정말 고생하셨습니다! 👍

PR에 말쑴해주신 것처럼
리모트 기기의 촬영 버튼 뷰에서 백버튼을 제거하는 게 깔끔할 것 같다는 생각이 드네요
물론 좌측 상단에 다시 버튼을 살려 홈으로 되돌려보내는 것도 있겠지만..
사용자가 촬영 도중에 연결 끊기나 뒤로가기 버튼을 누른다.라는 것 자체가 더 이상 앱을 사용하지 않거나 다시 실행하고 싶다는 의도로 볼 수 있을 것 같아서.. 지금처럼 없어도 될 것 같다는 의견입니다.

촬영 버튼과 같이 단순히 촬영 버튼만 있는 화면에서 정말 나가고 싶다면 연결 끊기 버튼보단 그냥 앱을 꺼버릴 것 같다는 생각도 드네용

다른 분들의 의견이 궁금합니다 👀

Comment on lines +223 to +218
private func handleDisconnection() {
send(.isPrimaryDeviceDisconnected)
browser.disconnect()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼭 분리할 필요가 있었을까? 라는 생각을 했지만
메서드 이름이 handleDisconnection이니 오히려 직관적으로 다가와서 좋은 것 같네요 👀

Copy link
Collaborator

@GRJeon GRJeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!
한 세 번 돌려보긴 했는데 잘 봤는지 모르겠습니다...

@GRJeon
Copy link
Collaborator

GRJeon commented Feb 5, 2026

정말 고생하셨습니다! 👍

PR에 말쑴해주신 것처럼 리모트 기기의 촬영 버튼 뷰에서 백버튼을 제거하는 게 깔끔할 것 같다는 생각이 드네요 물론 좌측 상단에 다시 버튼을 살려 홈으로 되돌려보내는 것도 있겠지만.. 사용자가 촬영 도중에 연결 끊기나 뒤로가기 버튼을 누른다.라는 것 자체가 더 이상 앱을 사용하지 않거나 다시 실행하고 싶다는 의도로 볼 수 있을 것 같아서.. 지금처럼 없어도 될 것 같다는 의견입니다.

촬영 버튼과 같이 단순히 촬영 버튼만 있는 화면에서 정말 나가고 싶다면 연결 끊기 버튼보단 그냥 앱을 꺼버릴 것 같다는 생각도 드네용

다른 분들의 의견이 궁금합니다 👀

백버튼 관련해선 앱 내 화면 전환 선택지를 줄 수 있으면 주는 것이 좋지 않을까라고 생각하긴 하지만 그럼에도 현 상황에서는 제거하는 것이 여러모로 괜찮은 선택지 같아요

Copy link
Collaborator

@opficdev opficdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sangYuLv sangYuLv removed the request for review from opficdev February 5, 2026 11:50
YunDaeHyeon and others added 8 commits February 5, 2026 20:53
- Browser는 계산 프로퍼티로 스트림을 노출
- HeartBeeater는 스트림 매니저의 yield 메서드 사용
- 테스트 코드 모두 통과로 동등성 확인 완료
- MCNearbyServiceBrowserDelegate 분리
- discoveredPeers 상태 관리 분리
- Browser는 browsingManager 인스턴스를 사용하도록 개선
- delegate extenstion 제거
- executeCommand 메서드를 CommandManager의 execute(data:)로 분리
- BrowserCommandDelegate Protocol 정의
- Browser에서 delegate 채택
- 기존 Browser.MirroringDeviceCommand, Browser.RemoteDeviceCommand 사용처에서 Browser. 만 제거
- BrowserManager 폴더 생성 및 관련 파일 이동
@sangYuLv sangYuLv force-pushed the refactor/#304-remote branch from 61d78d3 to 94b8b8f Compare February 5, 2026 12:01
@sangYuLv sangYuLv merged commit f14a60f into develop Feb 5, 2026
2 checks passed
@sangYuLv sangYuLv deleted the refactor/#304-remote branch February 5, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 fix 버그 수정 🔨 refactor 코드 리팩토링 (기능 변화 없이 구조 개선, 불필요한 import 제거)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CameraPreview에서 리모트 기기의 연결 끊김을 감지하지 못하는 문제를 해결한다.

4 participants