[objective-c] NSLocalizedString을 사용하는 모범 사례
(다른 모든 사람들과 마찬가지로) NSLocalizedString
내 앱을 현지화 하는 데 사용 하고 있습니다.
불행히도 다음을 포함하여 몇 가지 “결점”이 있습니다 (NSLocalizedString 자체의 결함 일 필요는 없음).
- Xcode에서 문자열에 대한 자동 완성이 없습니다. 이로 인해 오류가 발생하기 쉬울뿐만 아니라 번거 롭습니다.
- 이미 존재하는 동등한 문자열을 알지 못했기 때문에 단순히 문자열을 다시 정의하게 될 수 있습니다 (예 : “비밀번호를 입력하십시오”대 “비밀번호를 먼저 입력하십시오”)
- 자동 완성 문제와 마찬가지로 주석 문자열을 “기억”/ 복사해야합니다. 그렇지 않으면
genstring
한 문자열에 대해 여러 주석이 생깁니다. genstring
이미 일부 문자열을 현지화 한 후 사용하려면 이전 현지화를 잃지 않도록주의해야합니다.- 전체 프로젝트에 동일한 문자열이 흩어져 있습니다. 예를 들어
NSLocalizedString(@"Abort", @"Cancel action")
어디에서나 사용한 다음 코드 검토NSLocalizedString(@"Cancel", @"Cancel action")
에서 코드의 일관성을 높이기 위해 문자열의 이름을 바꾸도록 요청합니다 .
내가하는 일은 (그리고 많은 사람들이 이것을 찾은 후에 많은 사람들이 이것을하는 것으로 생각했습니다) 모든 현지화 코드 가있는 별도의 strings.h
파일 을 갖는 것 #define
입니다. 예를 들어
// In strings.h
#define NSLS_COMMON_CANCEL NSLocalizedString(@"Cancel", nil)
// Somewhere else
NSLog(@"%@", NSLS_COMMON_CANCEL);
이것은 본질적으로 코드 완성, 변수 이름을 변경하기위한 단일 위치 (더 이상 genstring 필요 없음) 및 자동 리팩터링을위한 고유 키워드를 제공합니다. 그러나 이것은 #define
본질적으로 구조화되지 않은 (예를 들어 LocString.Common.Cancel 또는 이와 유사한) 명령문 으로 끝납니다 .
그래서, 이것은 다소 효과가 있지만 프로젝트에서 어떻게하는지 궁금합니다. NSLocalizedString의 사용을 단순화하는 다른 접근 방법이 있습니까? 캡슐화하는 프레임 워크가 있을까요?
답변
NSLocalizedString
몇 가지 제한 사항이 있지만 Cocoa의 중심이기 때문에 현지화를 처리하기 위해 사용자 지정 코드를 작성하는 것은 부당합니다. 즉,이를 사용해야합니다. 약간의 툴링이 도움이 될 수 있습니다.
문자열 파일 업데이트
genstrings
문자열 파일을 덮어 쓰고 이전의 모든 번역을 버립니다. 내가 쓴 update_strings.py를 이전 문자열 파일, 실행 구문 분석 할 수 genstrings
있도록 수동으로 기존 번역을 복원 할 필요가 없다는 공백 및 채우기. 스크립트는 업데이트 할 때 너무 큰 차이를 피하기 위해 기존 문자열 파일을 가능한 한 가깝게 일치시킵니다.
문자열 이름 지정
NSLocalizedString
광고 한대로 사용 하는 경우 :
NSLocalizedString(@"Cancel or continue?", @"Cancel notice message when a download takes too long to proceed");
서로 다른 상황에서 다른 의미를 가질 수 같은 영어 용어로 충돌 할 수있는 코드의 다른 부분에서 같은 문자열을 정의 결국 (수 OK
와 Cancel
마음에 와서). 그렇기 때문에 항상 모듈 별 접두사와 매우 정확한 설명이있는 의미없는 올캡 문자열을 사용합니다.
NSLocalizedString(@"DOWNLOAD_CANCEL_OR_CONTINUE", @"Cancel notice window title when a download takes too long to proceed");
다른 장소에서 동일한 문자열 사용
동일한 문자열을 여러 번 사용하는 경우처럼 매크로를 사용하거나 View Controller 또는 데이터 소스에서 인스턴스 변수로 캐시 할 수 있습니다. 이 방법을 사용하면 설명이 반복되어 동일한 지역화 인스턴스 사이에서 오래되고 일관성이 없어 질 수 있습니다. 항상 혼란 스럽습니다. 인스턴스 변수는 기호이므로 가장 일반적인 번역에서 자동 완성 기능을 사용하고 특정 변수에 대해서는 “수동”문자열을 사용할 수 있습니다.이 문자열은 어쨌든 한 번만 발생합니다.
이 팁으로 Cocoa 현지화를 통해 생산성을 높이기를 바랍니다.
답변
Xcode에서 문자열의 자동 완성과 관련하여 https://github.com/questbeat/Lin을 시도 할 수 있습니다 .
답변
ndfred와 동의하지만 다음을 추가하고 싶습니다.
두 번째 파라미터는 … 기본값으로 사용할 수 있습니다 !!
(NSLocalizedStringWithDefaultValue는 genstring에서 제대로 작동하지 않으므로이 솔루션을 제안했습니다)
주석을 기본값으로 사용하는 NSLocalizedString을 사용하는 사용자 정의 구현은 다음과 같습니다.
1 . 사전 컴파일 된 헤더 (.pch 파일)에서 ‘NSLocalizedString’매크로를 재정의하십시오.
// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"
#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key comment:_comment]
2. 지역화 처리기를 구현할 클래스를 만듭니다.
#import "LocalizationHandlerUtil.h"
@implementation LocalizationHandlerUtil
static LocalizationHandlerUtil * singleton = nil;
+ (LocalizationHandlerUtil *)singleton
{
return singleton;
}
__attribute__((constructor))
static void staticInit_singleton()
{
singleton = [[LocalizationHandlerUtil alloc] init];
}
- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
// default localized string loading
NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];
// if (value == key) and comment is not nil -> returns comment
if([localizedString isEqualToString:key] && comment !=nil)
return comment;
return localizedString;
}
@end
3. 그것을 사용하십시오!
앱 빌드 단계에서 실행 스크립트를 추가해야 각 빌드마다 Localizable.strings 파일이 업데이트됩니다. 즉, 현지화 된 새 문자열이 Localized.strings 파일에 추가됩니다.
내 빌드 단계 스크립트는 쉘 스크립트입니다.
Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyClassesFolder
따라서 코드에 다음 줄을 추가하면
self.title = NSLocalizedString(@"view_settings_title", @"Settings");
그런 다음 빌드를 수행하면 ./Localizable.scripts 파일에 다음 줄이 포함됩니다.
/* Settings */
"view_settings_title" = "view_settings_title";
그리고 ‘view_settings_title’의 키 == 값이므로 사용자 정의 LocalizedStringHandler는 주석, 즉 ‘Settings’를 반환합니다.
Voilà 🙂
답변
스위프트에서는 다음과 같은 것을 사용하고 있습니다.
NSLocalizedString("btn_yes", value: "Yes", comment: "Yes button")
value:
기본 텍스트 값의 사용법에 유의하십시오 . 첫 번째 매개 변수는 번역 ID 역할을합니다. 이 value:
매개 변수 를 사용하면 나중에 기본 텍스트를 변경할 수 있지만 번역 ID는 동일하게 유지됩니다. Localizable.strings 파일에는"btn_yes" = "Yes";
경우 value:
매개 변수가 다음 사용되지 않은 첫 번째 매개 변수는 모두를 위해 사용되는 : 번역 ID과도 기본 텍스트 값. Localizable.strings 파일에는가 포함 "Yes" = "Yes";
됩니다. 이런 종류의 지역화 파일 관리는 이상하게 보입니다. 특히 번역 된 텍스트가 길면 ID도 길다. 기본 텍스트 값의 문자가 변경 될 때마다 번역 ID도 변경됩니다. 외부 번역 시스템을 사용할 때 문제가 발생합니다. 번역 ID를 변경하는 것은 항상 원치 않을 수있는 새로운 번역 텍스트를 추가하는 것으로 이해됩니다.
답변
Localizable.strings를 여러 언어로 유지 관리하는 데 도움이되는 스크립트를 작성했습니다. 자동 완성에는 도움이되지 않지만 다음 명령을 사용하여 .strings 파일을 병합하는 데 도움이됩니다.
merge_strings.rb ja.lproj/Localizable.strings en.lproj/Localizable.strings
자세한 내용은 https://github.com/hiroshi/merge_strings를 참조하십시오.
당신 중 일부는 내가 희망하는 것이 유용하다고 생각합니다.
답변
누군가 스위프트 솔루션을 찾고 있다면. 여기에 정리 한 솔루션을 확인하고 싶을 수도 있습니다. SwiftyLocalization
몇 단계 만 설정하면 Google 스프레드 시트에서 매우 유연한 현지화 (설명, 사용자 정의 색상, 강조 표시, 글꼴, 여러 시트 등)가 가능합니다.
간단히 말해 단계는 다음과 같습니다. Google 스프레드 시트-> CSV 파일-> Localizable.strings
또한 키 검색 및 디코딩에 대한 인터페이스처럼 작동하는 구조체 인 Localizables.swift도 생성합니다 (키에서 문자열을 디코딩하는 방법을 수동으로 지정해야 함).
왜 이것이 좋습니까?
- 더 이상 모든 장소에서 일반 문자열로 키를 가질 필요가 없습니다.
- 컴파일시 잘못된 키가 감지되었습니다.
- Xcode는 자동 완성을 수행 할 수 있습니다.
지역화 가능한 키를 자동 완성 할 수있는 도구가 있습니다. 실제 변수에 대한 참조는 항상 유효한 키인지 확인하고 그렇지 않으면 컴파일되지 않습니다.
// It's defined as computed static var, so it's up-to-date every time you call.
// You can also have your custom retrieval method there.
button.setTitle(Localizables.login.button_title_login, forState: .Normal)
이 프로젝트는 Google 앱 스크립트를 사용하여 시트-> CSV를 변환하고 Python 스크립트는 CSV 파일을 변환합니다-> Localizable.strings이 예제 시트를 빠르게 살펴보고 가능한 것을 알 수 있습니다.
답변
iOS 7 및 Xcode 5에서는 ‘Localization.strings’메소드를 사용하지 말고 새로운 ‘기본 현지화’메소드를 사용해야합니다. ‘기본 지역화’를 위해 Google을 사용하는 경우 몇 가지 자습서가 있습니다.
Apple Doc : 기본 현지화