본문 바로가기
프로그래밍 놀이터/iOS

[iOS Study] 지역화

by 돼지왕 왕돼지 2016. 3. 17.
반응형


 [iOS Study] 지역화


출처 : 아론 힐리가스의 iOS 프로그래밍


@selector, a, addObserver:selector:name:object:, append, Auto Layout, BASE, base internationalization, Base.lproj, Clean, Clean Build Folder, currency format, currentLocale, defaultCenter, en, English, en_US.lproj, Formatter, genstrings, i18n, ibtool, internationalization, internationalize, ios study, ios tutorial, Key, L10n, locale, localization, localize, localized xib, Lozalizable.strings, lproj, m 파일 지역화, mainbundle, nib, nil, nsbundle, NSCurrentLocaleDidChangeNotification, NSDateFormatter, NSLocale, NSLocaleCurrencySymbol, NSLocaleUsesMetricSystem, NSLocalizedString, nsnotificationcenter, NSNumberFormatter, NSNumberFormatterCurrencyStyle, NSString, numberStyle, objectForKey:, option, pathForResource:ofType:, Product, project tag, reinterpret, setting app, stringFromNumber, strings table, text encoding, text settings, UIViewController, US, use base internationalization, UTF-16, utf-8, xcode, XIB, XIB 파일, xocde, [iOS Study] 지역화, 강제 컴파일, 결함, 국제화, 기본 국제화, 기호, 날짜, 날짜 포맷, 다국어, 뒤집힌 물음표, 드래그, 디렉터리, 로케일, 리소스, 리소스 지역화, 리소스 파일, 리소스 파일 변경, 메뉴, 메인 번들, 문자열, 문자열 치환, 문자열 테이블, 문화 정보, 미국, 미터법, 번들, 번역 버전, 변수, 복사, 빌드, 사본, 사운드, 설정, 설정 앱, 수동, 숫자 포맷, 시뮬레이터, 십진수, 아론 힐리가스, 앱 번들, 앱 삭제, 언어, 언어 코드, 영어, 오토 레이아웃, 유니코드, 유틸리티, 유틸리티 영역, 이미지, 인스펙터 선택기, 인자, 인터프리트, 일반, 전체 컴파일, 접미사, 주석, 지역, 지역 코드, 지역 코드 optional, 지역 포맷, 지역화, 지역화된 xib, 최상위, 치환, 키-값, 터미널, 텍스트, 통화, 통화 포맷, 특화, 파인더, 파일 인스펙터, 편집, 표준, 프로젝트 내비게이터, 프로젝트 네비게이터, 프로퍼티, 플랫폼, 하드 코딩, 확장, 확장성


-

국제화(internationalization)은 각 나라의 고유 문화 정보를 앱에 하드 코딩 없이 적용하는 것이다.

(문화적 정보는 언어, 통화, 날짜 포맷, 숫자 포맷 등을 뜻한다.)



-

지역화(localization) 은 사용자의 언어와 지역 포맷 설정을 기반으로 앱에 적절한 데이터를 제공하는 과정이다.

이러한 설정은 설정 앱에서 찾을 수 있다.

[일반] 항목에서 [다국어] 열을 선택하면 된다.



-

internationalization 은 i18n 으로

localization 은 l10n 으로 축약해서 쓰기도 한다.



-

국제화는 NSDateFormatter 와 같은 Formatter 를 사용해서 구현한다.

NSDateFormatter 는 사용할 때마다 locale 프로퍼티를 확인하고 그에 따라 포맷을 설정한다.



-

NSLocale 은 기호, 날짜, 십진수 등이 지역마다 어떻게 다른지와 미터법을 사용하는지 등을 알고 있다.

NSLocale 에 currentLocale 메시지를 보내면 사용자의 지역 설정을 나타내는 NSLocale 인스턴스를 반환한다.

NSLocale 인스턴스를 갖고 나면 다음과 같이 물어볼 수 있다.

“ 이 지역의 통화 기호는 무엇인가?” 또는 “이 지역에서는 미터법을 사용하는가?"



-

NSLocale 인스턴스에 NSLocale 상수를 인자로 하여 objectForKey: 메시지를 보내 locale 관련 정보들을 얻을 수 있다.


NSLocale *locale = [NSLocale currentLocale];

BOOL isMetric = [[locale objectForKey:NSLocaleUsesMetricSystem] boolValue];

NSString *currencySymbol = [locale objectForKey:NSLocaleCurrencySymbol];



-

NSLocale 은 매우 강력하고 유용한 반면 항상 직접 사용하여 앱의 지역화 과정을 거쳐야 하므로 매우 지루하다.

그래서 Formatter 들을 사용하여 이를 감싼 것을 해결할 수 있다.



-

NSNumberFormatter 는 다음과 같이 사용할 수 있다.


NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];

NSString *numberAsString = [numberFormatter stringFromNumber:@123456.789];



-

NSNumberFormatter 는 통화의 포맷을 정하는 데도 매우 유용하다.

숫자 포매터의 numberStyle 프로퍼티를 NSNumberFormatterCurrencyStyle 로 설정하면 적절한 그룹과 소수점뿐만 아니라 통화 기호로 구성된 숫자를 만들어낼 것이다.


NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];

currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;

NSString *numberAsString = [currencyFormatter stringFromNumber:@123456.789];



-

지역 설정이 바뀔 때 앱에서 이를 확인하고 갱신하려면 NSNotificationCenter 를 사용해야 한다.

로케일 변경 노티피케이션을 등록 코드는 다음과 같다.


NotificationCenter *nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self

     selector:@selector(localeChanged:)

     name:NSCurrentLocaleDidChangeNotification

     object:nil];



-

국제화를 할 때 우리는 NSLocale 인스턴스에게 정보를 요청했었다.

그러나 NSLocale 은 몇몇 특정 지역의 변수만을 가지고 있다.

이 때문에 지역화를 사용하게 된다.

지역화는 지역과 언어 설정을 고려해 앱에 특화된 치환을 하는 과정이다.


지역화는 대개 둘 중 하나를 의미한다.

     각기 다른 지역과 언어에 대해 이미지, 사운드,  NIB 파일 등과 같은 리소스의 사본을 여러 개 만드는 것

     텍스트를 다른 언어로 번역한 문자열 테이블을 만들고 접근하는 것







-

이미지든 XIB 파일이든 간에 어떤 리소스든 지역화할 수 있다.

리소스의 지역화는 앱 번들 안에 사본을 여러 개 만드는 것이다.

이러한 리소스들은 lproj 디렉터리로 알려진 특정 언어 디렉터리에 구성된다

이러한 디렉토리 각각은 lproj를 접미사로 한 지역화의 이름이다.

예를 들어 미국 영어 지역화는 en_US.lproj 이다.

en 은 영어의 언어 코드이고 US 는 미국의 지역 코드이다. ( 지역 구분할 필요가 없다면, 지역 코드는 빼도 된다. )

이러한 언어와 지역 코드는 iOS 뿐만 아니라 모든 플랫폼에서 표준이다.



-

번들에 리소스 파일의 경로를 요청하면 그 이름의 파일을 제일 먼저 번들의 최상위에서 찾는다.

만약 찾지 못하면 장치의 로케일과 언어 설정을 확인하고 해당 lproj 디렉토리를 찾아 그 파일을 검색한다.

따라서 리소스 파일을 지역화하는 것만으로도 앱은 자동으로 올바른 파일을 불러올 것이다.



-

XIB 파일을 분리하여 만들고 Xcode 에서 이 XIB 파일의 문자열을 각각 수동으로 편집하는 방법도 있다.

그러나 이 방법은 여러 지역화를 계획하고 있다면 확장하기가 힘들다.



-

XCode 는 XIB 파일을 지역화하는 과정을 단순화하기 위해 기본 국제화(base internationalization)라는 기능을 가지고 있다.

이 기능이 프로젝트에 활성화돼 있다면 기본 국제화는 메인 XIB 파일을 가진 Base.lproj 디렉터리를 만든다.

그리고 개별 XIB 파일을 지역화하는 것은 Localizable.strings 파일을 만드는 것으로 완료할 수 있다.

문자열을 바꾸는 것만으로 지역화를 완료할 수 없는 경우에 완전한 XIB 파일을 만드는 것이 여전히 가능하다.

그러나 오토 레이아웃의 도움으로 대다수 지역화에는 문자열 치환만으로 충분할 것이다.



-

XIB 파일의 유틸리티 영역 -> 인스펙터 선택기 -> 파일 인스펙터 -> Localization -> Localize... 를 통해 지역화 설정을 할 수 있다.

English 를 선택하면, 이것은 이 XIB 파일이 지역화될 수 있다는 것은 XCode 에 알린다.

그리고 자동으로 en.lproj 을 만들고 해당 xib 파일을 그 디렉터리로 이동시킨다.


cf) XCode 의 특정 버전에서는 XIB 이 적어도 하나 이상 지역화되어야 Project 설정에서 지역화를 할 수 있었다.



-

프로젝트 파일을 선택하고, 그 안에 Project Tag 안의 프로젝트를 선택한다.

Info 탭의 아래쪽 영역에서 Localizations 섹션의 Use Base Internationalization 체크박스를 체크한다.

어느 파일을 기본 지역화로 만드는 데 사용할 것인지 물어본다.



-

Xcode 에는 작은 결함이 있다.

Xcode 는 종종 앱을 빌드할 때 리소스 파일의 변경을 무시한다.

앱을 처음부터 빌드하도록 장치나 시뮬레이터에서 그 앱을 지운다.

그리고, [Product] 메뉴에서 Clean 을 택한다.

Project 메뉴를 열고 Option 키를 누른 채로 [Clean Build Folder...] 를 선택하면 강제로 전체를 다시 컴파일하고 번들하여 재설치하게 한다.



-

문자열의 번역된 버전을 보여주려면 반드시 문자열 테이블(strings table)을 만들어야 한다.

문자열 테이블은 앱에서 사용한 모든 문자열과 해당 번역을 나타내는 키-값 쌍의 목록을 가진 파일이다.







-

문자열을 국제화하기 위해서는 NSLocalizedString  함수로 문자열 상수를 대체해야 한다.


NSString *greeting = NSLocalizedString(@“Hello!”, @“The greeting for the user”);


첫번째 인자가 key 인데, 이 키로 문자열 테이블에서 검색한다.

두번째 인자는 이 문자열을 설명하는 주석으로, tool 을 통해 string table 을 만들 때 자동으로 주석으로 만들어진다.

NSLocalizedString() 은 실행 중에 앱에 번들된 문자열 테이블을 살펴보고 사용자의 언어 설정과 일치하는 테이블을 찾는다.

그리고 이 함수는 그 테이블에서 키와 일치하는 번역 문자열을 얻는다.



-

NSLocalizedString 으로 지역화를 한 후에 터미널에서 아래 명령을 수행하면..


> genstrings LocalizeImpl.m


같은 디렉토리에 Localizable.string 이라는 파일이 생성된다.

해당 파일에 추가로 localize string 을 추가하려면 -a 옵션을 추가해줘야 한다.


> genstrings -a LocalizeImpl.m


생성된 파일을 프로젝트 내비게이터에 놓으면, 이 리소스는 앱이 컴파일 될 때 메인 번들에 복사된다.



-

이 파일을 열었을 때 만약 뒤집힌 물음표가 보인다면 유니코드(UTF-16)으로 다시 인터프리트 해야 한다.

유틸리티 -> 파일 인스펙터 -> Text Settings -> Text Encoding 을 UTF-16 으로 변경하고 Reinterpret 를 선택해야 한다.



-

Localizable.strings 에서 유틸리티 영역에서 Localize... 버튼을 눌러 지역화를 추가할 수 있다.



-

국제화를 추가하는 실제 작업은 NSBundle 클래스가 담당한다.

예를 들어, UIViewController 가 초기화될 때  XIB 파일의 이름과 NSBundle 객체의 두 인자를 받는다.

번들 인자는 일반적으로 nil 인데, 이것은 앱의 메인 번들을 처리하게 된다.

( 메인 번들은 앱의 모든 리소스와 실행 파일을 가진 앱 번들의 또 다른 이름이다.

모든 lproj 디렉토리는 앱이 빌드될 때 이 번들에 복사된다. )


뷰 컨트롤러가 뷰를 로드하면 XIB 파일을 번들에 요청한다.

번들은 매우 영리해서 장치의 현재 언어 설정을 확인하여 적절한 lproj 렉터리를 찾는다.

lproj 디렉토리의 XIB 파일경로는 뷰 컨트롤러에 반환되고 로드된다.


NSBundle 은 pathForResource:ofType:  인스턴스 메소드를 사용해 지역화 디렉터리에서 모든 종류의 리소스를 찾는 방법을 안다.

앱에 번들된 리소스의 경로를 얻길 원하면 이 메시지를 메인 번들에 보낸다.


[[NSBundle mainBundle] pathForResource:@“myImage” ofType:@“png”];


처음에 번들은 파일이 앱 번들의 최상위에 있는지 확인한다.

번들은 파일이 있다면 그 전체 경로를 반환하고, 그렇지 않다면 장치의 언어 설정을 가져와서 해당 lproj 디렉토리를 찾아 경로를 만든다.

결국 파일이 존재하지 않으면 nil 을 반환한다.


이것이 파일을 지역화할 때 앱을 삭제하고 정리해야 하는 이유이다.

이전의 지역화되지 않은 파일은 여전히 앱 번들의 최상위에 있을 것이다.

Xcode 는 재설치할 때 번들에서 파일을 지우지 않기 때문이다.

앱 번들에 lproj 폴더가 있더라도 번들은 최상위 파일을 먼저 찾고 그 경로를 반환한다.



-

이전에는 Base 국제화 기능이 없어 모든 로케일에 대한 XIB 파일을 관리했다.


지역화된 XIB 파일을 만들고 유지하는 데는 ibtool 이라는 커맨드라인 프로그램이 도움이 된다.

이 프로그램은 원어의 XIB 파일에서 문자열을 추출하여 strings 파일에 담는다.

그리고 이 문자열을 번역하여 각 언어에 대한 새로운 XIB 파일을 만들 수 있다.


이것은 현재는 잘 사용하지 않는 방법이므로, 자세한 설명은 생략한다.

인터넷 검색이나 책을 참조하길 바란다..



cf) 파인더에서 폴더 아이콘을 드래그하여 터미널 윈도우에 놓으면, 터미널에 해당 경로가 자동으로 채워진다.









반응형

'프로그래밍 놀이터 > iOS' 카테고리의 다른 글

[iOS Study] 상태 복원  (0) 2016.03.26
[iOS Study] 코어 데이터  (0) 2016.03.25
[iOS Study] UISplitViewController  (0) 2016.03.16
[iOS Study] 웹 서비스와 UIWebView  (0) 2016.03.15
[iOS Study] 유동글자  (0) 2016.03.09

댓글