[ios] NSLocalizedString이 특정 언어를 사용하도록하는 방법

iPhone에서 iPhone NSLocalizedString의 언어로 문자열을 반환합니다. NSLocalizedString앱을 기기와 다른 언어로 사용하기 위해 특정 언어 를 강제 로 사용할 수 있습니까?



답변

NSLocalizedString()(및 그 변형) “AppleLanguages”키에 액세스하여 NSUserDefaults원하는 언어에 대한 사용자 설정을 확인하십시오. 언어 코드 배열을 반환합니다. 첫 번째 언어는 사용자가 전화로 설정 한 언어이며, 이후 언어는 기본 언어로 리소스를 사용할 수없는 경우 대체로 사용됩니다. (데스크톱에서 사용자는 시스템 환경 설정에서 사용자 정의 순서로 여러 언어를 지정할 수 있습니다)

원하는 경우 setObject : forKey : 메소드를 사용하여 사용자 고유의 언어 목록을 설정하여 사용자 고유의 애플리케이션에 대한 글로벌 설정을 대체 할 수 있습니다. 전역 설정 값보다 우선하며 지역화를 수행하는 응용 프로그램의 모든 코드로 반환됩니다. 이에 대한 코드는 다음과 같습니다.

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate

이렇게하면 영어와 프랑스어를 대체 언어로 사용하여 독일어를 응용 프로그램에서 선호하는 언어로 만들 수 있습니다. 응용 프로그램을 시작할 때 언젠가이를 호출하려고합니다. 언어 / 로캘 기본 설정에 대한 자세한 내용은 다음을 참조하십시오. 국제화 프로그래밍 주제 : 현재 언어 및 로캘 얻기


답변

최근에 같은 문제가 발생하여 NSLocalizedString 전체를 시작하고 패치 하거나 새 언어가 작동하도록 앱을 강제로 다시 시작하고 싶지 않았습니다 . 나는 모든 것이 그대로 작동하기를 원했습니다.

내 솔루션은 기본 번들의 클래스를 동적으로 변경하고 적절한 번들을로드하는 것입니다.

헤더 파일

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

이행

#import <objc/runtime.h>

static const char _bundle=0;

@interface BundleEx : NSBundle
@end

@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Language)
+(void)setLanguage:(NSString*)language
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
    {
        object_setClass([NSBundle mainBundle],[BundleEx class]);
    });
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

따라서 기본적으로 앱이 시작되고 첫 번째 컨트롤러를로드하기 전에 다음을 호출하십시오.

[NSBundle setLanguage:@"en"];

사용자가 설정 화면에서 원하는 언어를 변경하면 다시 전화하십시오.

[NSBundle setLanguage:@"fr"];

시스템 기본값으로 다시 설정하려면 nil을 전달하면됩니다.

[NSBundle setLanguage:nil];

즐겨…

스위프트 버전이 필요한 분들 :

var bundleKey: UInt8 = 0

class AnyLanguageBundle: Bundle {

    override func localizedString(forKey key: String,
                                  value: String?,
                                  table tableName: String?) -> String {

        guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
              let bundle = Bundle(path: path) else {

            return super.localizedString(forKey: key, value: value, table: tableName)
            }

        return bundle.localizedString(forKey: key, value: value, table: tableName)
    }
}

extension Bundle {

    class func setLanguage(_ language: String) {

        defer {

            object_setClass(Bundle.main, AnyLanguageBundle.self)
        }

        objc_setAssociatedObject(Bundle.main, &bundleKey,    Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}


답변

나는 보통 이런 식으로이 작업을 수행하지만 프로젝트에 모든 지역화 파일이 있어야합니다.

@implementation Language

static NSBundle *bundle = nil;

+(void)initialize
{
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [defs objectForKey:@"AppleLanguages"];
    NSString *current = [[languages objectAtIndex:0] retain];
    [self setLanguage:current];
}

/*
  example calls:
    [Language setLanguage:@"it"];
    [Language setLanguage:@"de"];
*/
+(void)setLanguage:(NSString *)l
{
    NSLog(@"preferredLang: %@", l);
    NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
    bundle = [[NSBundle bundleWithPath:path] retain];
}

+(NSString *)get:(NSString *)key alter:(NSString *)alternate
{
    return [bundle localizedStringForKey:key value:alternate table:nil];
}

@end


답변

iOS 9에서는 사용하지 마십시오. 전달 된 모든 문자열에 대해 nil을 반환합니다.

앱을 다시 시작하지 않고 genstring과 호환되는 언어 문자열을 업데이트 할 수있는 또 다른 솔루션을 찾았습니다.

이 매크로를 Prefix.pch에 넣으십시오.

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]

지역화 된 문자열 사용이 필요한 곳 ​​:

NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")

언어 사용을 설정하려면 :

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];

다음과 같은 연속 언어 호핑에서도 작동합니다.

NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));


답변

앞서 말했듯이 다음과 같이하십시오.

[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];

그러나 앱을 다시 시작하지 않으려면 (…) main.m직전 의 주요 메소드에 줄을 넣으십시오 UIApplicationMain.


답변

앱에서 특정 언어를 선택하여 사용하는 요령 NSLocalizedString은 선택한 언어에 따라 특정 번들을 사용 하도록 강요하는 것입니다.

다음은 iOS 학습 앱 에서이 학습 고급 현지화를 위해 작성한 게시물입니다.

다음은 iOS 앱에서 하나의 샘플 앱 고급 지역화 코드입니다.


답변

Swift 3의이 솔루션에 대해 어떻게 생각하십니까?

extension String {

    func localized(forLanguage language: String = Locale.preferredLanguages.first!.components(separatedBy: "-").first!) -> String {

        guard let path = Bundle.main.path(forResource: language == "en" ? "Base" : language, ofType: "lproj") else {

            let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")!

            return Bundle(path: basePath)!.localizedString(forKey: self, value: "", table: nil)
        }

        return Bundle(path: path)!.localizedString(forKey: self, value: "", table: nil)
    }
}

간단한 사용법 :

"report".localized(forLanguage: "pl") //forced language
"report".localized() //default language selected by user in settings, in case when your app doesnt support selected lanaguage, the default one is selected, here is an english.