티스토리 뷰
이번에 개인 앱 하나를 출시했다. 개발 하면서 Localization 작업을 했는데
Xcode 15 에서 새로 나온 String Catalog 를 활용해 보다 편하게 현지화 기능을 적용했다.
사용해본 경험이 나쁘지 않아서 블로그로 정리해보려고 한다.
앱 내에 적용해보기
우선, 사용법은 굉장히 간단한데, String Catalog 파일을 일단 추가하고,
Xcode Project 의 Localizations 설정에서 사용할 언어를 입력해주면 준비는 끝난다.
이후 SwiftUI 와 UIKit 과 String.LocalizationValue 를 통해 쉽게 통합할 수 있다.
String(localized: LocalizedStringResource) 를 활용해 Localization 키를 등록할수도 있고, 적용한 String 값을 불러올 수 있다.
우선, 기존 Label 을 만드는 것 처럼 만들고, String(localized: ) 를 이용해 값을 넣어준다.
class MainViewController: UIViewController {
private let titleLabel: UILabel = {
let label = UILabel()
label.text = String(localized: "info.mainTitle")
label.font = .pretendard(.bold, 36)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
private let subTitleLabel: UILabel = {
let label = UILabel()
label.text = String(localized: "info.subTitle")
label.font = .pretendard(.medium, 20)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
}
이후 빌드를 하면 String Catalog 에 입력한 key가 바로 등록되는 것을 볼 수 있다!
이제 이곳에서 각 언어에 맞는 value 를 작성해주기만 하면 된다.
SwiftUI 에서는 아래처럼 더 쉽게 적용 가능하다.
struct ContentView: View {
var body: some View {
VStack {
Text("info.greeting")
}
.padding()
}
}
이렇게 코드를 작성하고 빌드하면, 바로 등록되는 것을 볼 수 있다.
새로 추가되었기 때문에 State는 New 라고 표시된다.
만약, 기존 빌드에 등록해서 사용중이던 key 가 다음 빌드에서 없어진다면, 다음처럼 warning 을 보여준다.
이전에 Localization 처럼 런타임에 문자열 중간 특정 값을 끼워넣는것도 가능하다.
struct ContentView: View {
let nickname = "Jason"
var body: some View {
VStack {
Text("info.greeting \(nickname)")
}
.padding()
}
}
이런식으로 nickname 을 넣어주게 되면, String Catalog 에서는 다음처럼 사용할 수 있다.
포맷 지정자를 변수처럼 활용하면 되는데 빵꾸를 두개 뚫면 이렇게 된다
확실히, 이전에 사용하는 방식보다 한눈에 보기 편해졌고, 소개하지 않은 다른 기능 (디바이스별, 각 숫자의 조건별 등) 도 쉽게 적용이 가능해 보인다.
Info Plist 현지화
info.plist 도 마찬가지로 String Catalog 를 활용해 Localization 적용할 수 있다. 다만, 별도의 파일을 만들어야 한다.
반드시 파일명을 InfoPlist 로! 만들어야 한다. 확장자까지 InfoPlist.xcstrings 로 만든다.
그리고 그곳에 현지화 된 value 를 입력하면 되는데, key 는 info.plist 의 key 와 동일하게 입력해주면 된다.
고민
코드에 String(localized: ..) 로 하드코딩 하기가 싫었다. 그래서 enum 으로 관리할 수 있도록 코드를 만들어 봤다.
class MainViewController: UIViewController {
private let titleLabel: UILabel = {
let label = UILabel()
label.text = Localization.mainTitle.localizedString
label.font = .pretendard(.bold, 36)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
private let subTitleLabel: UILabel = {
let label = UILabel()
label.text = Localization.subTitle.localizedString
label.font = .pretendard(.medium, 20)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
}
enum Localization: String {
case mainTitle
case subTitle
var key: LocalizedStringResource {
return .init(stringLiteral: rawValue)
}
var localizedString: String {
return String(localized: key)
}
}
String Catalog 는 이렇게 코드를 만든 경우에 key 를 자동 등록하지 않는다.
수동으로 Catalog 에 key를 추가해주면 런타임에서는 동작하긴 하는데, 컴파일 단계에서 관리가 되지 않으면 String Catalog 의 핵심 기능을 사용하지 못하는거나 다름 없다고 생각한다.
최종적으로는 코드에 직접 String(localized: ) 를 입력하는 방식으로 코드를 작성하긴 했다.
작업을 계속 하다보니 생각 드는 것은 내가 enum 으로 key 들을 관리하려고 했던 의도가 key 누락이나 변경 등 유지보수에 원활히 대응하고자 함이였는데, 사실 String Catalog 에서 이미 컴파일 할 때마다 관리를 해주고 있어서 불필요하겠다고 생각은 들었다.
그래도 어떻게 사용해야 더 효율적으로 활용할 수 있는 방법이 있을지?
더 작업하면서 고민해봐야겠다.
'iOS' 카테고리의 다른 글
[iOS] MVI 패턴과 테스트코드 적용하기 (1) | 2025.05.13 |
---|---|
[iOS] STOMP 로 채팅 구현하기 (0) | 2025.05.11 |
[iOS] SwiftUI 에서 TapGesture 가 동작하지 않을 때 (HighPriorityGesture) (1) | 2025.03.23 |
[iOS] Swift로 오디오 다루기 (AudioKit) (0) | 2025.03.16 |
[iOS] Open API Generator 로 네트워크 코드 자동생성(2) - middleware로 토큰 관리, interceptor (0) | 2024.10.29 |
- Total
- Today
- Yesterday
- openapi-generator
- ios 다국어
- avplayer
- 맥북에어 m4
- highprioritygesture
- watch connectivity
- Swift
- audiokit
- swift날짜
- audio kit
- string catalog
- keyboardtype
- SwiftUI
- self-hosted-runner
- ios채팅
- easy cue
- swiftui 탭
- flo
- swiftui 제스처
- Xcode15
- DateFormatter
- demical
- AVFoundation
- swift audio
- IOS
- Github action
- open-api-generator
- onTapGesture
- 애플워치 데이터 전송
- ios웹소켓
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |