글로벌 사용자를 대상으로 iOS 앱을 개발한다면 다국어 지원은 필수적입니다.
다행히도 Xcode에는 다국어 처리를 쉽게 구현할 수 있도록 되어 있습니다.
오늘은 Xcode 14 이하의 버전에서 다국어 처리를 하는 방법에 대해 알아보겠습니다.
String catalog를 이용한 방법은 다음 포스트에 작성하겠습니다.
다국어 처리는 무엇을 기준으로 해야 할까요?
"국가마다 다르게" 라고 생각할 수도 있지만 그렇지 않습니다.
한국으로 여행온 일본인일 수도 있잖아요!
그렇다면 기준을 "사용자가 사용하는 언어"로 해야 합니다.
조금 더 나아가서, "사용자가 기기에 설정한 언어" 로 다국어 처리를 하는게 맞겠죠.
우리는 GIF 파일 경로의 언어 설정에 맞도록 처리할 예정입니다.
프로젝트에 Strings file을 추가해 줍니다.
간단하게 김치를 번역해보겠습니다.
이 때 반드시 세미콜론(;)을 끝에 붙여줘야 합니다.
Text("김치")로 표현한 것이 kimchi로 표현이 되었습니다.
아주 간단하게 다국어 처리가 완료된 것입니다!
여기서 잠깐. 저는 한국어를 사용하는 한국인인데 우리말을 왜 영어로 번역하고 있나요?
프로젝트 파일에서 언어를 더 추가하겠습니다.
Localizations 아래에 + 를 눌러 한국어, 일본어를 추가하겠습니다.
그리고 이번 예제에서는 한국어를 기본 언어(default)로 설정하겠습니다.
이제 Localizable.strings 파일로 돌아가서 인스펙터 영역을 연 후, Localize...
버튼을 눌러줍니다.
위 버튼을 모두 선택해주면 모든 언어로 번역할 수 있게 strings 파일이 바뀝니다.
이렇게 해준 후, 각 strings 파일에서 원하는 형태로 번역을 해주면 됩니다.
우리가 아까 한국어를 기본 언어(default)로 설정했죠? 그렇기 때문에 이제 한국어를 한국어로 번역(?)을 하게 됩니다.
#Preview에 .environment(\.locale, .init(identifier: "en"))
를 붙여주시면 됩니다.
어... 했는데도 안 되는데요
-> Xcode 버그입니다. 다른 버전을 열거나 종료 후 다시 열어주세요.
-> 그래도 안 되면 clean build 하고 preview를 다시 열어 보세요.
위 방법으로 진행하는 다국어 처리는 많은 반복 작업이 필요합니다.
또한, 번역이 누락되거나 잘못된 경우에도 컴파일 과정에서 에러로 나타나지 않습니다.
때문에 사람이 하나씩 수동으로 번역을 처리하다 보면 실수가 발생할 수 있습니다.
이런 Human Error를 줄이고, 번역 작업을 자동화하는 방법에 대해 알아보겠습니다.
우선 I18N.swift 파일을 만들어 줍니다.
(I18N은 Internationalization의 약자입니다. 다른 이름으로 하려면 script 일부를 수정해 주세요)
Target의 Build Settings에 들어간 후 User Script Sandboxing을 No로 처리해 줍니다.
Target에서 Build Phase를 선택하고, + 버튼을 눌러 스크립트를 추가해 줍니다.
#!/bin/sh
echo "generating I18N.swift"
touch tempI18N.swift
echo "import Foundation" >> tempI18N.swift
echo >> tempI18N.swift
echo "enum I18N {" >> tempI18N.swift
inputfile=${SRCROOT}/${PROJECT}/ko.lproj/Localizable.strings
while IFS= read -r line
do
echo $line
pattern='^.+=.+$'
comment='\/\/.+'
if [[ $line =~ $pattern ]]
then
echo "Yes👌"
variableWithQuote=$(echo ${line%%=*})
variableWithoutQuote=$(echo "$variableWithQuote" | sed 's/^"\(.*\)"$/\1/')
variableName=$(echo "$variableWithoutQuote" | tr -d '. /-')
echo $variableName
if [ "$variableName" != "" ]; then
echo " static let $variableName: String = \"$variableName\".localized" >> tempI18N.swift
fi
else
if [[ $line =~ $comment ]]
then
echo "Comment 📝"
echo "\n $line" >> tempI18N.swift
else
echo "No👎"
fi
fi
done <"$inputfile"
echo "}" >> tempI18N.swift
echo >> tempI18N.swift
echo "extension String {" >> tempI18N.swift
echo " var localized: String {" >> tempI18N.swift
echo " return NSLocalizedString(self, comment: \"\")" >> tempI18N.swift
echo " }" >> tempI18N.swift
echo "}" >> tempI18N.swift
cat tempI18N.swift > ${SRCROOT}/${PROJECT}/I18N.swift
rm tempI18N.swift
아래와 같이 설정을 변경해 주세요.
이후 빌드를 하게 되면 매 빌드마다 깔끔하게 관리되는 enum 파일을 만들 수 있습니다.
이렇게 되면 View에서 나타내야 할 String 값들을 I18N.swift에서 한번에 관리할 수 있습니다.
(아래 사진은 Xcode preview가 번역을 안하고 말썽을 피워서 시뮬레이터로 찍었습니다.)
Xcode 14 이하에서 다국어 처리 방법에 대해서 알려드렸습니다.
Xcode 16이 나온 시점에서 이 방법을 포스팅한 이유는 String catalog를 사용할 수 없고, iOS 버전이 낮은 사람들이 할 수 있는 최선의 방법을 알려드리기 위함입니다.
참고로 위 내용은 모두 UIKit에서 활용이 가능합니다.
오늘 배운 스크립트를 활용한 방법은 매 빌드마다 자동으로 enum 파일을 생성함으로써 사람이 발생시킬 수 있는 오류를 최소화하여 효율성과 안정성을 높이는 방법을 알려드렸습니다.
다음 포스팅에서는 String catalog를 활용하는 방법을 알려드리고, 과정에서 발생할 수 있는 많은 이슈들을 함께 알아보겠습니다.