开发者

How to localize text based on criterion other than language

I have an application which will be marketed in different European countries. We've gone throu开发者_开发百科gh the process of localizing the application so that its strings are maintained in the language-specific .lproj files in the Settings.bundle. This all works fine. The problem is that there are some strings which don't key off language, but off the country where the app is run. For example, there are strings which differ between the Austrian version of the app and the German version of the app, even though both these countries speak German. When it's run for the first time, the app asks the user which country it's running in.

Is there a way in which I can maintain these country-specific strings in a resource file, and have the resource file used at run time be decided by a user setting, in this case the country where the app is running, rather than the device language?

Thanks,

Peter Hornby


Define two bundles on a singleton, fallback and preferred...

#import <Foundation/Foundation.h>

@interface Localization : NSObject

@property (nonatomic, retain) NSString* fallbackCountry;
@property (nonatomic, retain) NSString* preferredCountry;

@property (nonatomic, retain) NSDictionary* fallbackCountryBundle;
@property (nonatomic, retain) NSDictionary* preferredCountryBundle;

+(Localization *)sharedInstance;
- (NSString*) countryStringForKey:(NSString*)key;

@end


#import "Localization.h"

@implementation Localization

@synthesize fallbackCountryBundle, preferredCountryBundle;
@synthesize fallbackCountry, preferredCountry;

+(Localization *)sharedInstance 
{
    static dispatch_once_t pred;
    static Localization *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[Localization alloc] init];

        [shared setFallbackCountry:@"country-ES"];

        NSLocale *locale = [NSLocale currentLocale];
        NSString *countryCode = [locale objectForKey:NSLocaleCountryCode];
        [shared setPreferredCountry:[NSString stringWithFormat:@"country-%@",countryCode]];
    });
    return shared;
}


-(void) setFallbackCountry:(NSString*)country
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:country ofType:@"strings"];
    self.fallbackCountryBundle = [NSDictionary dictionaryWithContentsOfFile:bundlePath];
    trace(@"Fallback: %@ %@",[bundlePath lastPathComponent], self.fallbackCountryBundle);
}


-(void) setPreferredCountry:(NSString*)country 
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:country ofType:@"strings"];
    self.preferredCountryBundle = [NSDictionary dictionaryWithContentsOfFile:bundlePath];

    BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:nil];
    if (!exists) warn(@"%@.strings %@", country, exists ? @"FOUND" : @"NOT FOUND");

    trace(@"Preferred: %@ %@",[bundlePath lastPathComponent], self.preferredCountryBundle);
}


- (NSString*) countryStringForKey:(NSString*)key 
{
    NSString* result = nil;
    if (preferredCountryBundle!=nil) result = [preferredCountryBundle objectForKey:key];
    if (result == nil) result = [fallbackCountryBundle objectForKey:key];
    if (result == nil) result = key;

    return result;
}


@end

Then call it from a macro function

#define countryString(key) [[Localization sharedInstance]countryStringForKey:key];

Write a default file for ES, and one file per supported language. eg:

/* 
  country-ES.strings
*/

"hello" = "hello";

And just get the value for the key:

countryString(@"hello");
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜