From 243da1eb7da8a610c1f1d6336451b14e07c04e08 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Wed, 1 Apr 2026 18:44:05 +0900 Subject: [PATCH] =?UTF-8?q?fix(i18n):=20=EC=98=88=EC=95=BD=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=EC=99=80=20=EC=8B=9C=EA=B0=84=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EC=96=B8=EC=96=B4=EB=A5=BC=20=EC=95=B1=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EC=B6=98=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Content/Create/ContentCreateView.swift | 5 ++- .../Create/QuarterTimePickerView.swift | 3 +- .../Content/Create/SelectDatePicker.swift | 3 +- .../Sources/Extensions/DateExtension.swift | 4 +- .../Live/Room/Create/LiveRoomCreateView.swift | 9 ++-- docs/20260401_예약일시언어적용.md | 41 +++++++++++++++++++ 6 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 docs/20260401_예약일시언어적용.md diff --git a/SodaLive/Sources/Content/Create/ContentCreateView.swift b/SodaLive/Sources/Content/Create/ContentCreateView.swift index a9c4110..9de3fbd 100644 --- a/SodaLive/Sources/Content/Create/ContentCreateView.swift +++ b/SodaLive/Sources/Content/Create/ContentCreateView.swift @@ -9,6 +9,7 @@ import SwiftUI import Kingfisher struct ContentCreateView: View { + @Environment(\.locale) private var locale @StateObject var keyboardHandler = KeyboardHandler() @StateObject private var viewModel = ContentCreateViewModel() @@ -541,7 +542,7 @@ struct ContentCreateView: View { hideKeyboard() self.isShowSelectDateView = true }) { - Text(viewModel.releaseDateString) + Text(viewModel.releaseDate.convertDateFormat(dateFormat: "yyyy.MM.dd", locale: locale)) .appFont(size: 14.7, weight: .medium) .foregroundColor(Color.grayee) .frame(maxWidth: .infinity) @@ -562,7 +563,7 @@ struct ContentCreateView: View { hideKeyboard() self.isShowSelectTimeView = true }) { - Text(viewModel.releaseTimeString) + Text(viewModel.releaseTime.convertDateFormat(dateFormat: "a hh:mm", locale: locale)) .appFont(size: 14.7, weight: .medium) .foregroundColor(Color.grayee) .frame(maxWidth: .infinity) diff --git a/SodaLive/Sources/Content/Create/QuarterTimePickerView.swift b/SodaLive/Sources/Content/Create/QuarterTimePickerView.swift index 0712c6f..670b310 100644 --- a/SodaLive/Sources/Content/Create/QuarterTimePickerView.swift +++ b/SodaLive/Sources/Content/Create/QuarterTimePickerView.swift @@ -8,6 +8,7 @@ import SwiftUI struct QuarterTimePickerView: View { + @Environment(\.locale) private var locale @Binding var selectedTime: Date @Binding var isShowing: Bool @@ -28,7 +29,7 @@ struct QuarterTimePickerView: View { ) .datePickerStyle(WheelDatePickerStyle()) .labelsHidden() - .environment(\.locale, Locale.init(identifier: "ko")) + .environment(\.locale, locale) .frame(width: proxy.size.width - 53.4) .onAppear { UIDatePicker.appearance().minuteInterval = 15 diff --git a/SodaLive/Sources/Content/Create/SelectDatePicker.swift b/SodaLive/Sources/Content/Create/SelectDatePicker.swift index a332526..01a134a 100644 --- a/SodaLive/Sources/Content/Create/SelectDatePicker.swift +++ b/SodaLive/Sources/Content/Create/SelectDatePicker.swift @@ -8,6 +8,7 @@ import SwiftUI struct SelectDatePicker: View { + @Environment(\.locale) private var locale @Binding var selectedDate: Date @Binding var isShowing: Bool @@ -24,7 +25,7 @@ struct SelectDatePicker: View { DatePicker("", selection: $selectedDate, in: Date()..., displayedComponents: .date) .datePickerStyle(WheelDatePickerStyle()) .labelsHidden() - .environment(\.locale, Locale.init(identifier: "ko")) + .environment(\.locale, locale) .frame(width: proxy.size.width) Button(action: { self.isShowing = false }) { diff --git a/SodaLive/Sources/Extensions/DateExtension.swift b/SodaLive/Sources/Extensions/DateExtension.swift index ce2ba87..f53e55e 100644 --- a/SodaLive/Sources/Extensions/DateExtension.swift +++ b/SodaLive/Sources/Extensions/DateExtension.swift @@ -8,10 +8,10 @@ import Foundation extension Date { - func convertDateFormat(dateFormat: String = "yyyy.MM.dd") -> String { + func convertDateFormat(dateFormat: String = "yyyy.MM.dd", locale: Locale = .autoupdatingCurrent) -> String { let formatter = DateFormatter() formatter.dateFormat = dateFormat - formatter.locale = Locale.autoupdatingCurrent + formatter.locale = locale formatter.timeZone = TimeZone.current return formatter.string(from: self) } diff --git a/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift b/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift index 48955d4..de3644c 100644 --- a/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift +++ b/SodaLive/Sources/Live/Room/Create/LiveRoomCreateView.swift @@ -9,6 +9,7 @@ import SwiftUI import Kingfisher struct LiveRoomCreateView: View { + @Environment(\.locale) private var locale @StateObject var keyboardHandler = KeyboardHandler() @StateObject var viewModel = LiveRoomCreateViewModel() @@ -532,7 +533,7 @@ struct LiveRoomCreateView: View { hideKeyboard() self.isShowSelectDateView = true }) { - Text(viewModel.reservationDateString) + Text(viewModel.reservationDate.convertDateFormat(dateFormat: "yyyy.MM.dd", locale: locale)) .appFont(size: 14.7, weight: .medium) .foregroundColor(Color.grayee) .frame(width: buttonWidth, height: 48.7) @@ -552,7 +553,7 @@ struct LiveRoomCreateView: View { hideKeyboard() self.isShowSelectTimeView = true }) { - Text(viewModel.reservationTimeString) + Text(viewModel.reservationTime.convertDateFormat(dateFormat: "a hh : mm", locale: locale)) .appFont(size: 14.7, weight: .medium) .foregroundColor(Color.grayee) .frame(width: buttonWidth, height: 48.7) @@ -604,7 +605,7 @@ struct LiveRoomCreateView: View { DatePicker("", selection: $viewModel.reservationDate, in: Date()..., displayedComponents: .date) .datePickerStyle(WheelDatePickerStyle()) .labelsHidden() - .environment(\.locale, Locale.autoupdatingCurrent) + .environment(\.locale, locale) .frame(width: proxy.size.width) Button(action: { self.isShowSelectDateView = false }) { @@ -635,7 +636,7 @@ struct LiveRoomCreateView: View { DatePicker("", selection: $viewModel.reservationTime, displayedComponents: .hourAndMinute) .datePickerStyle(WheelDatePickerStyle()) .labelsHidden() - .environment(\.locale, Locale.autoupdatingCurrent) + .environment(\.locale, locale) .frame(width: proxy.size.width - 53.4) Button(action: { self.isShowSelectTimeView = false }) { diff --git a/docs/20260401_예약일시언어적용.md b/docs/20260401_예약일시언어적용.md new file mode 100644 index 0000000..46f6461 --- /dev/null +++ b/docs/20260401_예약일시언어적용.md @@ -0,0 +1,41 @@ +# 20260401 예약 일시 언어 적용 + +## 작업 체크리스트 +- [x] 앱 언어 설정 주입 경로와 예약 날짜/시간 로케일 override 지점을 확인한다. +- [x] `LiveRoomCreateView` 예약 날짜/시간 표시가 앱 설정 언어를 따르도록 수정한다. +- [x] `ContentCreateView` 예약 날짜/시간 표시가 앱 설정 언어를 따르도록 수정한다. +- [x] 예약용 날짜/시간 picker가 앱 설정 언어를 따르도록 수정한다. +- [x] 변경 사항을 diagnostics/build/manual QA로 검증한다. + +## 수용 기준 (Acceptance Criteria) +- [x] `LiveRoomCreateView`의 예약 날짜/시간 버튼 텍스트가 앱 설정 언어 기준으로 표시된다. +- [x] `ContentCreateView`의 예약 날짜/시간 버튼 텍스트가 앱 설정 언어 기준으로 표시된다. +- [x] 두 화면의 날짜/시간 picker가 앱 설정 언어 기준으로 표시된다. +- [x] 예약 API 전송 포맷(`yyyy-MM-dd`, `HH:mm`)은 변경되지 않는다. + +## 구현 메모 +- 앱 루트 `SodaLiveApp`에서 `.environment(\.locale, languageEnvironment.locale)`를 이미 주입하고 있다. +- 이번 작업은 생성 화면과 picker 내부의 locale override 제거/교체만 수행한다. +- 전역 날짜 포맷 기본 동작은 변경하지 않고, 대상 화면에서만 앱 locale을 명시 사용한다. + +## 검증 기록 +- 2026-04-01: 탐색 완료 + - 무엇: 앱 언어 source of truth와 예약 날짜/시간 표시 경로 확인 + - 왜: 시스템 locale 대신 앱 설정 locale을 따라야 하는 실제 수정 지점 식별 필요 + - 어떻게: `LanguageService`, `SodaLiveApp`, `DateExtension`, 생성 화면/피커 구현 확인 + - 결과: 앱 루트 locale 주입은 이미 존재하며, 생성 화면에서 picker/date text가 이를 덮어쓰는 것이 원인으로 확인됨 +- 2026-04-01: 구현 및 검증 완료 + - 무엇: 생성 화면 예약 날짜/시간 텍스트와 picker locale을 앱 설정 locale 기준으로 수정 + - 왜: 시스템 언어와 앱 설정 언어가 다를 때 예약 UI가 항상 한국어 또는 시스템 locale로 표시되던 문제 해결 필요 + - 어떻게: + - `LiveRoomCreateView`, `ContentCreateView`에서 버튼 텍스트를 `Date.convertDateFormat(..., locale: locale)`로 표시 + - `LiveRoomCreateView`, `SelectDatePicker`, `QuarterTimePickerView`에서 picker locale override를 앱 environment locale로 교체 + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` 실행 + - `swift` 스크립트로 동일 시각 포맷을 `ko_KR`/`en_US`/`ja_JP`에 대해 출력 확인 + - 결과: + - Debug build 성공 (`** BUILD SUCCEEDED **`) + - 포맷 출력 확인 + - `ko_KR`: `오후 09:15` + - `en_US`: `PM 09:15` + - `ja_JP`: `午後 09:15` + - 예약 API 전송용 `yyyy-MM-dd`, `HH:mm` 포맷 코드는 변경하지 않음