iOS开发--应用国际化,应用内切换语言

时间:2022-10-14 20:22:22

1.前言

自己负责的项目需要做国际化,并且要求应用内部切换语言。这个是可以做到的,也并不难,可以直接戳Github看一下

https://github.com/leo90821/LocaliztionStringExchange

2.实现原理

原理比较简单,利用NSBundle切换语言包,主要利用NSBundle的方法 

- localizedStringForKey:value:table: 进行本地字符串的切换

3.实现代码

1)业务逻辑

头文件

#import <Foundation/Foundation.h>

#define USER_DEFAULT_STRING @"userLanguage"
#define APPLE_LANGUAGES @"AppleLanguages"
/**
 * App BLL
 **/
@interface BLL : NSObject
/**
 * BLL single
 **/
+ (instancetype)currentLogic;
/**
 * App bundle
 **/
+ (NSBundle *)bundle;
/**
 * 初始化语言
 **/
- (void)initUserLanguage;
/**
 * 获得当前语言
 **/
- (NSString *)getCurrentLanguage;
/**
 * 设置语言
 **/
- (void)setUserLanguageWithLanguage:(NSString *)language;
@end

实现文件

 

#import "BLL.h"

@implementation BLL
static NSBundle *bundle = nil;

- (instancetype)init {
    self = [super init];
    return self;
}

+ (instancetype)currentLogic {
    static BLL *logic = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        logic = [[BLL alloc] init];
    });
    return logic;
}

+ (NSBundle *)bundle {
    return bundle;
}

/**
 * 初始化语言
 **/
- (void)initUserLanguage {
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSString *string = [userDefault valueForKey:USER_DEFAULT_STRING];
    if (string.length == 0) {
        NSArray *languages = [userDefault objectForKey:APPLE_LANGUAGES];
        NSString *current = [languages objectAtIndex:0];
        string = current;
        [userDefault setValue:string forKey:USER_DEFAULT_STRING];
        [userDefault synchronize];
    }
    
    NSString *path = [[NSBundle mainBundle] pathForResource:string ofType:@"lproj"];
    bundle = [NSBundle bundleWithPath:path];
}
/**
 * 获得当前语言
 **/
- (NSString *)getCurrentLanguage {
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSString *language = [userDefault valueForKey:USER_DEFAULT_STRING];
    return language;
}
/**
 * 设置语言
 **/
- (void)setUserLanguageWithLanguage:(NSString *)language {
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSString *path = [[NSBundle mainBundle] pathForResource:language ofType:@"lproj"];
    bundle = [NSBundle bundleWithPath:path];
    [userDefault setValue:language forKey:USER_DEFAULT_STRING];
    [userDefault synchronize];
}

@end

2)视图控制器

#import <UIKit/UIKit.h>
#define NOTIFICATION_CHANGE_LANGUAGE @"ChangeLanguage"
@interface ViewController : UIViewController
@end
#import "ViewController.h"
#import "BLL.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *tip;

- (IBAction)changeLanguage:(id)sender;
@property (weak, nonatomic) IBOutlet UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self.button setTitle:NSLocalizedStringFromTable(@"Change", @"MyString", nil) forState:UIControlStateNormal];
    self.tip.text = NSLocalizedStringFromTable(@"Hello", @"MyString", nil);

}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self addObservers];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self removeObservers];
}

- (void)addObservers {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshUI) name:NOTIFICATION_CHANGE_LANGUAGE object:nil];
}

- (void)removeObservers {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NOTIFICATION_CHANGE_LANGUAGE object:nil];
}

- (void)refreshUI {
    
    [self.button setTitle:[[BLL bundle] localizedStringForKey:@"Change" value:nil table:@"MyString"] forState:UIControlStateNormal];
    self.tip.text = [[BLL bundle] localizedStringForKey:@"Hello" value:nil table:@"MyString"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)changeLanguage:(id)sender {
    NSString *language = [[BLL currentLogic] getCurrentLanguage];
    
    if ([language rangeOfString:@"en"].location != NSNotFound) {
        [[BLL currentLogic] setUserLanguageWithLanguage:@"zh-Hans"];
    } else {
        [[BLL currentLogic] setUserLanguageWithLanguage:@"en"];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_CHANGE_LANGUAGE object:nil
     ];
}
@end

 

4.小结

原理比较简单,利用NSBundle切换语言包,主要利用NSBundle的方法 

- localizedStringForKey:value:table: 进行本地字符串的切换,最麻烦的是刷新每个页面都需要设置消息观察者,这个就比较蛋疼。有没有好的方法,欢迎留言交流。