스위프트(Swift)를 사용한 iOS 프로젝트에서 로컬라이징하는 방법입니다.

  1. 프로젝트 세팅
  2. 스토리보드 로컬라이징
  3. 코드 내 텍스트의 로컬라이징
  4. 변수값을 사용하는 어순이 바뀌는 언어의 로컬라이징
  5. info.plist 로컬라이징

 

1. 프로젝트 세팅

프로젝트 세팅의 PROJECT > Info 에서 Localizations 아래에 있는 + 버튼을 클릭합니다.

 

여기서는 한국어(ko)를 선택하도록 하겠습니다. 여러 언어를 추가할 수 있습니다.

 

기본 언어를 선택할 때, 영어를 기반으로 작업한 다음 기타 언어를 추가하는 방법을 추천합니다. 위의 그림을 보면 EnglishDevelopment Language라고 설정되어 있는데 이것을 한국어로 바꾸려면 귀찮은 작업이 추가됩니다. 애초에 다국어화를 염두해 두고 있다면 영어를 기본 언어로 Base에서 개발을 진행하고, 현지화는 다른 언어들로 하는게 좋을 것 같습니다. (개발 언어 변경하는 방법 stackoverflow)

 

2. 스토리보드 로컬라이징

위에서 언어를 선택하면 위와 같은 창이 뜹니다. 여기서 스토리보드 목록이 나오는데 현지화가 필요한 스토리보드를 체크하고 Finish를 누릅니다.

 

Main 스토리보드에 펼치기 버튼이 새로 생기며, 하위 메뉴에 Main(Korean)이라는 메뉴가 생깁니다. 이것을 클릭합니다.

 

클릭하면 위와 같이 번역 서식을 자동으로 생성해줍니다. 초록색 부분을 참고로 하여 빨간색 라인의 오른쪽 부분을 아래와 같은 방식으로 해당 언어로 번역하면 됩니다.

 

앱을 실행하고 언어를 변경하면 위와 같이 영어와 한국어가 다르게 표기되는것을 볼 수 있습니다.

 

현지화 작업은 앱 개발의 마지막 단계에서 하는 것을 추천합니다. 앱 중간에 추가되거나 변경되는 사항이 있을 경우 스토리보드는 변경 사항을 언어별로 모두 업데이트해야 합니다. (스토리보드 로컬라이징 파일 업데이트 하는 방법 stackoverflow)

 

3. 코드 내 텍스트의 로컬라이징

스토리보드 외에 컨트롤러 등의 코드에서 텍스트를 다룰 일이 있습니다.

먼저 아래와 같은 Stringextension을 추가합니다.

extension String {
    
    var localized: String {
        return NSLocalizedString(self, tableName: "Localizable", value: self, comment: "")
    }
    
    func localizedFormat(_ arguments: CVarArg...) -> String {
        let localizedValue = self.localized
        return String(format: localizedValue, arguments: arguments)
    }
}

 

NSLocalizedString 함수는 키, 원문을 저장하여 언어별 빌드마다 번역된 결과를 제공하는 역할을 합니다.

func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String
  • key – 번역의 대상이 되는 키를 설정합니다.
  • tableName – 번역 정보가 담겨져 있는 테이블을 선택합니다. Localizable라는 이름의 테이블을 이용할 것입니다.
  • value – 원문 텍스트입니다. 기본 언어 또는 번역 정보가 없을경우 반환되는 텍스트입니다.
  • comment – 이 키에 관한 주석을 입력하면 현지화 Export 기능 이용시 정보 파일의 키 위에 주석이 표시됩니다. 여기서는 번역 정보를 Export 기능을 사용하지 않고 수동으로 입력하므로 코멘트란은 비워둡니다.

 

번역 테이블 파일을 생성합니다. 프로젝트에서 새 파일을 생성합니다. Strings FIle을 선택합니다.

파일 이름을 Localizable.strings로 설정합니다. (대소문자 및 철자 주의)

 

Localizable.strings 파일을 연 뒤 Xcode 창 오른쪽의 File Inspector에서 Localize... 버튼을 클릭합니다.

 

아래와 같은 창이 나오면 Base 가 있는 경우 Base, 없는 경우 개발 언어인 English 를 선택합니다.

File Inspector으로 다시 돌아가서 번역 대상 언어를 선택합니다. English는 번역할 필요가 없으므로 체크 해제합니다.

 

먼저 코드에서 번역이 필요한 텍스트 옆에 .localized 를 추가합니다. 아래는 .localized 를 사용하는 예제의 일부입니다.

let alertTitle = "Unable to Create".localized

guard selectedDocument != nil else {
    simpleAlert(self, message: "You must select a file to upload.".localized, title: alertTitle) { action in
        self.scrollView.setContentOffset(.zero, animated: true)
    }
    return false
}

guard txfPostTitle.text! != "" else {
    simpleAlert(self, message: "Please enter the title.".localized, title: alertTitle) { action in
        self.txfPostTitle.becomeFirstResponder()
    }
    return false
}

 

번역할 텍스트가 정해졌으면, Localizable.strings 파일을 열어 아래와 같은 형식으로 작성합니다.

"Unable to Create" = "만들 수 없음";

"You must select a file to upload." = "업로드할 파일을 선택해야 합니다.";
"Please enter the title." = "제목을 입력해주세요.";

왼쪽은 키(key) , 오른쪽은 번역할 텍스트를 입력합니다. .localized 에서 키는 원문과 같으므로 원문을 왼쪽에 추가하고, 오른쪽에 번역을 입력합니다.

각 라인 끝마다 세미콜론(;)을 반드시 입력해야 합니다. 세미콜론 누락시 오류가 발생하며 컴파일러에서 위치를 알려주지 않으므로 주의해야 합니다

 

이런식으로 진행하면 코드 내 텍스트도 로컬라이징을 진행할 수 있습니다.

 

4. 변수값을 사용하는 어순이 바뀌는 언어의 로컬라이징

3. 에서 이어지는 내용입니다. 알다시피, 영어와 한국어는 어순이 다릅니다. 그런데 텍스트 내에서 특정 변수값을 사용해야 하는 경우가 있습니다.

  • “He said the food James ate was chicken.”
  • “그가 말하길 제임스 씨가 먹은 음식은 치킨이라고 하네요.”

 

이러한 케이스에서, 단일 언어로 개발하는 경우 \(variableName)을 사용해서 텍스트를 추가하면 됩니다.

let name = "제임스" 
let food = "치킨" 
let text = "그가 말하길 \(name) 씨가 먹은 음식은 \(food)이라고 하네요."

 

하지만 여러 언어로 현지화되는 경우, 어순이 변화하기 때문에 어순을 고려하면 위와 같은 방법은 사용하기가 어렵습니다. 이런 경우 스트링의 format 기능을 이용한 포맷이 적용된 텍스트를 이용할 수 있습니다.

 

3. 번에서 추가했던 Stringextension 중 아래 코드를 다시 살펴보겠습니다.

func localizedFormat(_ arguments: CVarArg...) -> String {
    let localizedValue = self.localized
    return String(format: localizedValue, arguments: arguments)
}
  • localizedValue는 로컬라이징된 텍스트입니다.
  • String(format:arguments:)printf 와 비슷한 텍스트 포맷을 적용하여 스트링을 변환합니다. 사용법은 대체로 printf와 비슷합니다. 맨 처음에 포맷 적용된 텍스틀 넣고, 그 다음 각각 포맷 지정자(format specifier)에 해당하는 변수들을 파라미터 형태로 입력합니다.
  • CVarArg... 는 이후의 모든 파라미터들의 정보를 받아들입니다. 예를 들어 (variable1, variable2, variable3) 인 경우 모든 변수 정보가 arguments 라는 단일 변수 안에 배열 형태와 비슷하게 들어갑니다.  이 변수를 스트링 포맷의 arguments 에 할당하면 파라미터를 여러개 입력받을 수 있습니다.

 

포맷을 사용할 때 글자가 꺠지는 문제가 있어서 스트링값에 대한 포맷 지정자는 %s 대신 %@ 를 사용합니다. 코드를 작성합니다.

let localizeSample = "He said the food %@ ate was %@.".localizedFormat("James".localized, "chicken".localized)
print(localizeSample)
  • “He said the food %@ ate was %@.” 와 같이 변수가 필요한 자리에 %@를 삽입합니다.
  • localizedFormat(…) 에서 각 지정자에 해당하는 변수를 파라미터 형태로 입력합니다.

 

다음 Localized.strings 파일을 작성합니다.

"He said the food %@ ate was %@." = "그가 말하길 %@ 씨가 먹은 음식은 %@이라고 하네요.";
"James" = "제임스";
"chicken" = "치킨";

첫줄과 같이 해당하는 포맷 지정자를 적절한 위치에 넣으면 됩니다.

 

5. info.plist 로컬라이징

위 그림은 info.plist 파일에서 카메라, 사진 라이브러리 사용자 권한을 묻는 메시지를 적는 곳입니다. 여기에 작성된 문구도 당연히 현지화를 해야 합니다.

 

InfoPlist.strings 라는 이름의 스트링즈 파일을 작성합니다. (대소문자 및 철자 주의)

 

다음 File Inspector에서 로컬라이징 대상 언어를 추가합니다 (3. 번 내용과 같음)

 

스트링즈 파일은 키와 값으로 이루어집니다.

info.plist 에서 마우스 오른쪽 버튼 클릭후 Source Code 로 열기를 선택합니다. (원래 표 형태로 보고 싶은 경우 Property List 선택)

XML 형태의 프로퍼티 리스트가 표시됩니다.

여기서 key 값을 텍스트를 역추적하여 찾습니다.

<key>NSCameraUsageDescription</key>
<string>Camera permission is required to take a user&apos;s profile picture.</string>

<key>NSPhotoLibraryUsageDescription</key>
<string>Photo Library permission is required to upload a user&apos;s profile picture from the library.</string>

여기서 키는 NSCameraUsageDescription, NSPhotoLibraryUsageDescription 두가지가 있으며, 전자는 카메라 권한, 후자는 사진 라이브러리 권한입니다.

 

위의 키를 사용하여 아래와 같이 InfoPlist.strings 파일을 작성합니다.

NSCameraUsageDescription = "사용자 프로필 사진을 촬영하기 위한 카메라 권한 허용이 필요합니다.";
NSPhotoLibraryUsageDescription = "사용자 프로필 사진을 가져오기 위한 사진 라이브러리 권한 허용이 필요합니다.";

컴파일러 에러 방지를 위해 라인 끝마다 세미콜론(;)을 반드시 입력해야 합니다.

 


문의 | 코멘트 또는 yoonbumtae@gmail.com  donaricano-btn

카테고리: Swift

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다