用于简化 Objective C 中单例方法调用的宏,以执行类似 NSLocalizedString 的操作

Macro to simplify Singleton method calls in Objective C to do something like NSLocalizedString

我想在我的 iOS 应用程序中支持一些 Apple 不支持的语言。所以我创建了一个单例来管理这个东西:

#import "Translator.h"

@implementation Translator {

    NSDictionary* _langDictionary;
    NSString* _selectedLang;
}

NSString* kDefaultLang = @"es_ES";
NSString* kLangKey = @"lang";

+ (id)sharedManager {
    static Translator *sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedManager = [[self alloc] init];
    });
    return sharedManager;
}

- (id)init {
    if (self = [super init]) {
        _selectedLang = [[NSUserDefaults standardUserDefaults] stringForKey:kLangKey];
        if (_selectedLang == nil) {
            _selectedLang = kDefaultLang;
        }
        else {
            [self loadLang:_selectedLang];
        }
    }
    return self;
}

- (void) saveLang:(NSString*)lang{
    [[NSUserDefaults standardUserDefaults] setObject:lang forKey:kLangKey];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void) loadLang:(NSString*) selectedLang {
    if ([selectedLang isEqualToString:kDefaultLang]) {
        [self saveLang:kDefaultLang];
        NSLog(@"Default Languaje loaded");
    }
    else {
        // Check if languaje file exists in mainBundle
        NSString *langPath = [[NSBundle mainBundle] pathForResource:selectedLang ofType:@"plist"];
        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:langPath];
        // If exists, load the lang file
        if (fileExists) {
            [self saveLang:selectedLang];
            _langDictionary = [NSDictionary dictionaryWithContentsOfFile:langPath];
            NSLog(@"Languaje %@ loaded", selectedLang);
        }
        else {
            NSLog(@"Error loading: %@ languaje.",selectedLang);
            [self loadLang:kDefaultLang];
        }
    }
}

- (NSString*)translationForKey:(NSString*)key defaultText:(NSString*)text {

    NSString* translation;

    if (_selectedLang != kDefaultLang) {
        translation = [_langDictionary objectForKey:key];
    }
    
    if (translation == nil) {
        translation = text;
    }
    
    return translation;
}

@end

我想创建一个宏来简化单例调用。像 NSLocalizedString 这样的东西。而不是写:

[[Translator sharedManager] translationForKey:@"key" defaultText:@"defaultText"]

我想得到这样的翻译:

NSLocalizedString(@"key", @"defaultText");

但是我不知道我要写什么来定义这个宏:

Translate(@"key",@"defaultText")

目前,我使用的是几乎相同的翻译结构。

#define DICT(key) [[[MPConnector sharedConnector] getAllTranslations] valueForKey:key]

我这样称呼它;

someLabel.text = DICT(@"NOW_LISTENING");

你可以试试;

#define Translate(key, default) [[Translator sharedManager] translationForKey:key defaultText:default]

P.S: 我没有尝试使用多个参数的宏,但我的效果很好。