NSLocalizedString을 사용하는 모범 사례
(다른 사람들과 마찬가지로) 사용하고 있습니다.NSLocalizedString
내 앱을 현지화합니다.
유감스럽게도 다음과 같은 몇 가지 "결함"(NSLocalizedString 자체의 결함은 아님)이 있습니다.
- Xcode의 문자열에 대한 자동 완성 기능이 없습니다.이것은 작업을 오류 발생 가능성이 높을 뿐만 아니라 피곤하게 만듭니다.
- 동일한 문자열이 이미 존재하는지 몰랐기 때문에 문자열을 재정의할 수 있습니다(예: "암호를 입력하십시오" 대 "암호를 먼저 입력하십시오").
- 문제와 , 문자열을 "하여 붙여넣어야 않으면 "기억"/"기억"/"기억"이 필요합니다.
genstring
의 문자열에 개의 댓글을 . - 당신이 경우용을 사용하고 .
genstring
일부 문자열을 이미 현지화한 후에는 이전 현지화가 손실되지 않도록 주의해야 합니다. - 프로젝트 전체에 동일한 문자열이 흩어져 있습니다.예를 들어, 다음과 같이 사용한
NSLocalizedString(@"Abort", @"Cancel action")
모든 곳에서 코드 검토를 수행한 다음 문자열의 이름을 변경하도록 요청합니다.NSLocalizedString(@"Cancel", @"Cancel action")
코드의 일관성을 높입니다.
제가 하는 일(그리고 SO에 대한 몇 가지 검색 후 많은 사람들이 이것을 한다는 것을 알게 되었습니다)은 별도의 것을 갖는 것입니다.strings.h
내가 있는 곳에 줄을 서라.#define
모든 로컬라이즈 코드.를 들어, .
// In strings.h
#define NSLS_COMMON_CANCEL NSLocalizedString(@"Cancel", nil)
// Somewhere else
NSLog(@"%@", NSLS_COMMON_CANCEL);
이것은 기본적으로 코드 완성, 변수 이름을 변경할 수 있는 단일 장소(더 이상 genstring이 필요하지 않음) 및 자동 리팩터를 위한 고유 키워드를 제공합니다.하지만, 이것은 결국 많은 사람들에게 대가를 치르게 됩니다.#define
LocString과 같이 본질적으로 구조화되지 않은 문.공통. 취소 등).
그래서, 이것이 어느 정도 잘 작동하지만, 저는 여러분들이 프로젝트에서 어떻게 하는지 궁금합니다.NSLocalizedString의 사용을 단순화하기 위한 다른 접근법이 있습니까?그것을 캡슐화하는 프레임워크가 있을까요?
NSLocalizedString
몇 가지 제한 사항이 있지만, 코코아에서는 매우 중요하기 때문에 현지화를 처리하기 위해 사용자 지정 코드를 작성하는 것은 불합리합니다. 즉, 이 코드를 사용해야 합니다.다시 말해, 약간의 툴링이 도움이 될 수 있습니다. 제가 진행하는 방법은 다음과 같습니다.
문자열 파일 업데이트 중
genstrings
문자열 파일을 덮어쓰고 이전 변환을 모두 삭제합니다.이전 문자열 파일을 구문 분석하기 위해 update_strings.py를 작성했습니다.genstrings
기존 번역을 수동으로 복원할 필요가 없도록 빈칸을 채웁니다.스크립트는 기존 문자열 파일을 업데이트할 때 너무 큰 차이가 발생하지 않도록 가능한 한 가깝게 일치시킵니다.
문자열 이름 지정
사용하는 경우NSLocalizedString
광고된 대로:
NSLocalizedString(@"Cancel or continue?", @"Cancel notice message when a download takes too long to proceed");
될 수 , 는 동일한 가 다른 수 입니다(" 드의다부동서문있될며수으정게코의다하니있수습자충다있때, " 동한영용가어른수컨가어텍다스", "돌할에문기트질에서의를미른일른분에일을열한▁you").OK
그리고.Cancel
모듈별와 매우 정확한합니다.그렇기 때문에 모듈별 접두사와 매우 정확한 설명이 있는 의미 없는 all-caps 문자열을 항상 사용합니다.
NSLocalizedString(@"DOWNLOAD_CANCEL_OR_CONTINUE", @"Cancel notice window title when a download takes too long to proceed");
다른 위치에서 동일한 문자열 사용
동일한 문자열을 여러 번 사용하는 경우 매크로를 사용하거나 뷰 컨트롤러 또는 데이터 원본에서 인스턴스 변수로 캐시할 수 있습니다.이렇게 하면 동일한 현지화의 인스턴스 간에 오래되고 일관성이 없을 수 있는 설명을 반복할 필요가 없습니다. 이러한 설명은 항상 혼동을 일으킵니다.인스턴스 변수는 기호이므로 가장 일반적인 변환에서는 자동 완성을 사용할 수 있으며, 특정 변환에서는 "수동" 문자열을 사용할 수 있습니다. 이 문자열은 어차피 한 번만 발생합니다.
이 팁들로 코코아 현지화로 생산성이 향상되기를 바랍니다!
Xcode의 문자열 자동 완성에 대해서는 https://github.com/questbeat/Lin 을 사용해 볼 수 있습니다.
엔드프레드의 말에 동의하지만, 저는 이것을 추가하고 싶습니다.
두 번째 매개 변수는 ... 기본값으로 사용할 수 있습니다!!
(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]
로컬리제이션 처리기를 구현할 클래스 만들기
#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
사용하세요!
각 빌드에서 Localizable.strings 파일이 업데이트되도록 App 빌드 단계에서 실행 스크립트를 추가해야 합니다. 즉, 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_proxy_proxy'에 대한 키 == 값이 있으므로 사용자 지정 LocalizedStringHandler는 설명(예: 'Settings')을 반환합니다.
Voila :-)
Swift에서는 예를 들어 이 경우 "예" 버튼에 대해 다음을 사용합니다.
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.string을 유지 관리하는 데 도움이 되는 스크립트를 작성했습니다.자동 완성에는 도움이 되지 않지만 다음 명령을 사용하여 .strings 파일을 병합하는 데 도움이 됩니다.
merge_strings.rb ja.lproj/Localizable.strings en.lproj/Localizable.strings
자세한 내용은 https://github.com/hiroshi/merge_strings 를 참조하십시오.
도움이 되시는 분들도 계실 겁니다.
Swift 솔루션을 찾는 사람이 있다면요.제가 여기에 정리한 솔루션을 확인해 보십시오: Swifty Localization
설정하는 몇 가지 단계가 없어도 Google 스프레드시트(주석, 사용자 지정 색상, 강조 표시, 글꼴, 여러 시트 등)에서 매우 유연한 현지화를 수행할 수 있습니다.
간단히 말해서, 단계는 Google 스프레드시트 --> CSV 파일 --> Localizable.strings입니다.
또한 키 검색 및 디코딩에 대한 인터페이스 역할을 하는 구조인 Localizables.swift를 생성합니다(단, 키에서 String을 디코딩하는 방법은 수동으로 지정해야 합니다).
왜 이렇게 좋은 거죠?
- 더 이상 모든 플레이스에 일반 문자열로 키를 사용할 필요가 없습니다.
- 컴파일 시 잘못된 키가 검색됩니다.
- 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 App Script를 사용하여 Sheets --> CSV를 변환하고 Python 스크립트를 사용하여 CSV 파일을 변환합니다. --> Localizable.strings 이 예제 시트에서 무엇이 가능한지 간단히 확인할 수 있습니다.
iOS 7 및 Xcode 5에서는 'Localization.strings' 메서드를 사용하지 말고 새로운 'Base localization' 메서드를 사용해야 합니다.'기본 현지화'를 검색하면 몇 가지 튜토리얼이 있습니다.
Apple 문서: 기본 현지화
#define PBLocalizedString(key, val) \
[[NSBundle mainBundle] localizedStringForKey:(key) value:(val) table:nil]
저 자신도 .strings 파일에 항목을 넣는 것을 잊어버리고 코딩에 열중하는 경우가 많습니다.따라서 .strings 파일에 다시 넣고 번역해야 할 내용을 찾기 위한 도우미 스크립트가 있습니다.
NSLocalizedString을 통해 내 매크로를 사용하므로 NSLocalizedString의 두 번째 매개 변수로 nil이 사용되는 단순성을 위해 사용하기 전에 스크립트를 검토하고 업데이트하십시오.변경하고자 하는 부분은
NSLocalizedString\(@(".*?")\s*,\s*nil\)
매크로 및 NSLocalizedString 사용과 일치하는 것으로 바꾸기만 하면 됩니다.
대본이 나옵니다. 3부만 있으면 됩니다.나머지는 모든 것이 어디에서 발생하는지 쉽게 확인하는 것입니다.
// Part 1. Get keys from one of the Localizable.strings
perl -ne 'print "$1\n" if /^\s*(".+")\s*=/' myapp/fr.lproj/Localizable.strings
// Part 2. Get keys from the source code
grep -n -h -Eo -r 'NSLocalizedString\(@(".*?")\s*,\s*nil\)' ./ | perl -ne 'print "$1\n" if /NSLocalizedString\(@(".+")\s*,\s*nil\)/'
// Part 3. Get Part 1 and 2 together.
comm -2 -3 <(grep -n -h -Eo -r 'NSLocalizedString\(@(".*?")\s*,\s*nil\)' ./ | perl -ne 'print "$1\n" if /NSLocalizedString\(@(".+")\s*,\s*nil\)/' | sort | uniq) <(perl -ne 'print "$1\n" if /^\s*(".+")\s*=/' myapp/fr.lproj/Localizable.strings | sort) | uniq >> fr-localization-delta.txt
출력 파일에는 Localizable.strings 파일에는 없지만 코드에서는 발견된 키가 포함되어 있습니다.다음은 샘플입니다.
"MPH"
"Map Direction"
"Max duration of a detailed recording, hours"
"Moving ..."
"My Track"
"New Trip"
물론 더 닦을 수 있지만, 공유하고 싶습니다.
언급URL : https://stackoverflow.com/questions/9895621/best-practice-using-nslocalizedstring
'sourcecode' 카테고리의 다른 글
Xcode + 모든 중단점 제거 (0) | 2023.05.13 |
---|---|
TesseractNotFound 오류를 해결하려면 어떻게 해야 합니까? (0) | 2023.05.13 |
__builtin_과 __builtin_의 차이점은 무엇입니까? (0) | 2023.05.13 |
GitHub: 공공 저장소의 포크를 비공개로 만드는 방법은 무엇입니까? (0) | 2023.05.13 |
PostgreSQL에서 업데이트 + 가입하는 방법은 무엇입니까? (0) | 2023.05.13 |