문법 검사 기능 추가 및 Live Actovity 추가합니다.#279
Conversation
- 빌드 시 상시 초기화 합니다.
- tooltip을 보기 좋게 나오도록 수정 - mlxGrammarRepository 의존성 추가
- 문법 교정 후 container를 살려 다시 loadModel을 하지 않도록 KVCache만 비웁니다.
- transcript -> grammarCheck -> 요약 순으로 진행 되며 분석 상테에 따로 호출되는 함수 또한 수정하였습니다.
- 가끔 불필요한 json데이터를 주는 경우를 방어하고자 추가하였습니다.
- 음성 노트 진입 시 요약, 문법 교정을 진행 하지 않는 문제를 찾았습니다. 분석 Service의 노트를 큐잉하여 시작하거나 재개 하도록 수정.
- enqueue Preview 적용 - 분석 상태 추가에 따른 뷰 프로퍼티 수정
- 각 Section의 text를 respond 하지만 이럴 경우 모델의 추론 능력이 뛰어기에 respond 후 clearCache로 계속 KVCache가 늘어나는걸 방지합니다. 결과: 평균 2.7GB ~ 3.1GB 까지 최적화 소요시간은 늘어났습니다..
- 대기 작업의 원복 상태 보존을 위한 `QueueJob` 도입 및 대기열 로직 구현 - 활성 분석 작업이 있을 경우 대기열로 진입시키고 DB 상태를 `.waiting`으로 전환 - 요약/문법교정 Task 도중 entries.removeValue가 호출되어 취소 불가를 유도하던 버그 수정 - cancel, cancelAll, revertState 내 대기 상태(.waiting) 원복 및 해제 로직 보완 -UI(VoiceNoteSummaryViewController)에 누락된 .waiting switch 분기 추가
- 모듈 분리 및 app - info 활성화 - 테스트 타겟 추가
- 5.8의 경우 Int 형변환에서 5로 적용되는것을 발견.. -> rounded로 반올림 하여 6GB로 적용합니다.
- Widget Process와 App Process는 별개로 notificationCenter를 사용 하지 못하므로 DarwinNotificationCenter를 사용합니다.
- 잠금화면 TimerView를 HStack과 Spacer로 감싸 재생 중 왼쪽으로 붙는 버그 및 매초 위치가 흔들리는 현상(Jittering) 해결 - LockScreenView 우측 VStack의 불필요한 `.frame(width: .infinity)` 제거 - compactTrailing 영역의 TimerView를 고정 크기(38x24)의 ZStack으로 감싸고 `.clipped()`를 적용하여 다이내믹 아일랜드가 가로로 늘어나는 현상 방지
- 병렬처리는 메모리 OOM우려로 제외 - 5개씩 묶어서 문법검사를 처리 - 전체를 묶어서 한번 검사하는게 가장 빠르겠지만 이것도 KVCache 폭주
- 배칭 응답 파싱 및 실패 시 원본 텍스트를 유지하는 예외 처리 추가 - 디버그 빌드 시 메인 스레드 병목 해결을 위해 임시 오디오 파일 생성 길이 제한 (최대 5초) -'SeedContent'에 'buildLongSections' 복구 및 'grammarCheckTest' 맞춤법 오류 데이터 적용 - 문법 교정 진행률을 AppLogger.info로 실시간 로깅하도록 변경 -AppLogger 레벨 변경: info -> debug
- Fastfile에 위젯 Bundle ID 추가 및 배포 빌드 시 프로비저닝 프로파일 매핑 적용 - Widget/Project.swift에 위젯 타겟 수동 코드사인 및 프로파일(match) 세팅 추가 - ChaGokWidgetTests 컴파일 대상에 누락된 위젯 소스 파일들을 포함하여 링커 에러 해결
There was a problem hiding this comment.
Code Review
This pull request introduces a Live Activity recording widget with IPC communication via Darwin notifications, and integrates an on-device grammar correction pipeline using MLX. Feedback on these changes highlights several issues in the new grammar repository, such as a potential memory leak from not releasing the MLX model on success, a parsing bug with out-of-bounds indices, a missing progress notification, and unhandled cooperative cancellation. Additionally, there is a potential compilation error in the widget due to a missing TimeInterval extension, and duplicate widget source files should be cleaned up.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
🛠️ Tuist Run Report 🛠️Tests 🧪
Builds 🔨
|
✨ 작업 요약
📋 구체적인 내용
• 추가/변경된 동작:
• 문법 검사 최적화 (Prompt Batching): 문장을 1개씩 순차적으로 검사하던 방식에서 5개씩 묶어서 한 번에
검사(Batching)하는 방식으로 개선하여 온디바이스 LLM 추론 속도를 3~5배 향상하고 메모리 점유율을 최소화했습니다.
• 예외 처리 및 폴백: 배칭 결과 파싱 실패 시 원본 텍스트를 유지하는 폴백 로직을 추가하여 데이터 안정성을
확보했습니다.
• 위젯 코드사인 설정 (Fastlane Match): 위젯 타겟( com.yongms.ChaGokChaGok.widget )을 Fastlane match 동기화 대상
및 build_app 프로비저닝 프로파일 매핑에 추가하여 배포 자동화(CI/CD) 환경을 마련했습니다.
• 위젯 타겟 빌드 설정: Widget/Project.swift 에 수동 코드사인 설정을 적용했습니다.
• 위젯 테스트 빌드 에러 해결: ChaGokWidgetTests 타겟이 LiveAudioMeter 등의 위젯 소스에 접근할 수 있도록,
@main 이 정의된 WidgetBundle.swift 를 제외한 위젯의 모든 소스 파일을 테스트 타겟 컴파일 대상에 포함시켰습니다.
• 영향 받는 화면/모듈:
• Data / Domain (문법 교정 레포지토리 및 정책)
• Widget / WidgetTests (위젯 타겟 및 테스트 프로젝트 설정)
• fastlane (배포 스크립트)
──────
🔗 연관 이슈 #278
• closed #
──────
🧩 설계·구현 노트
│ 왜 이렇게 구현했는지, 대안과 비교한 점 (선택)
• 선택한 방식
• 문법 검사 - 프롬프트 배칭(Prompt Batching): 120개의 문장을 5개씩 묶어 총 24번의 호출로 단축했습니다. 3B급 소형
온디바이스 모델의 특성상 컨텍스트가 너무 길어지면 메모리 부족(OOM)이나 문장 누락이 발생하므로, 5개씩 나누어
처리하여 메모리 효율과 추론 속도의 최적의 균형을 맞췄습니다.
• 위젯 테스트 소스 포함: 앱 익스텐션 타겟은 테스트 타겟에 직접 링크할 수 없으므로, @main 진입점을 가진
WidgetBundle.swift 만 제외한 채 모든 소스 파일을 테스트 타겟의 컴파일 소스로 지정하여 링커 에러를 방지했습니다.
• 고려했다가 제외한 방식
• 전체 문장을 한 번에 처리 (배칭 사이즈 120): 온디바이스 환경에서 수천 토큰의 KV 캐시가 누적되어 OOM 크래시가
발생할 위험이 크고, 소형 모델 특성상 지시 이행력이 떨어져 문장이 누락되거나 포맷이 깨지는 현상이 발생하여
제외했습니다.
• 단순 병렬 처리 (Bounded Concurrency - TaskGroup): 애플 실리콘 GPU의 메모리 대역폭 한계로 인해 병렬로 돌려도
속도가 향상되지 않고 컨텍스트 스위칭 부하 및 메모리 피크만 높아져 제외했습니다.
──────
✅ 확인 사항
│ PR 전 직접 확인한 것
[✓] 정상 플로우 동작 확인 (로컬 빌드 및 코드사인 확인)
[✓] 엣지 케이스 / 빈 값·에러 처리 확인 (배칭 파싱 실패 시 원본 텍스트 유지 폴백 로직 검증)
[ ] (UI 변경 시) 스크린샷 또는 GIF 첨부
[ ] (로직 추가 시) 테스트 추가 여부
──────
👀 리뷰 포인트
[✓] 설계·구조 적절성 (5개 단위 배칭 구조 및 파싱 로직의 안전성)
[✓] 로직·엣지 케이스 (배칭 결과가 부정확할 때의 예외 처리)
[✓] 성능·의존성 (AppLogger의 레벨 조정을 통해 실서비스 빌드 시 로그 미노출 처리 확인)
특히 봐줬으면 하는 부분
• DefaultMLXGrammarRepository 의 parseBatchResponse 정규식 파싱 로직이 다양한 모델 출력 형태( [1] , 1. , 1: )와
줄바꿈 상황을 안전하게 지원하는지 검토 부탁드립니다.
──────
📚 참고
• 문법 검사 최적화 결과, 디버그 빌드 시 메인 스레드 병목 및 화면 프리징 현상이 완전히 해결되었습니다.