IOS百行代码全局语言本地化/国际化

IOS本地化/国际化项目配置

废话不多说先把基本配置搞定图文一起来

3618569F-C518-4582-8580-9DC73F1E8B2E.png

这里点个“+”直接就o了
剩下的就是创建strings文件也就是语言映射文件

32E018FA-1E4C-4127-BD87-0AE0B0B1641D.png

划线的就是创建时候该点击的InfoPlist.strings就是定义CFBundleDisplayName来确定app的名字
Localizable.strings则是正经的语言映射表了
xib,storyboard和image也是一个套路看划线那点击就ok了


6DCE952A-4868-4652-AAB5-59C36DF129D5.png

百行代码全局Hook完成本地化

废话不多说先放代码在解释
https://github.com/heroims/LocalizedEngine

#import "LocalizedEngine.h"
#import <objc/runtime.h>
#import <UIKit/UIKit.h>

#define LocalizedString(string) NSLocalizedString(string, nil)

@interface NSObject (LocalizedEngineSwizzling)

@end
@implementation NSObject (LocalizedEngineSwizzling)

+ (BOOL)les_swizzleMethod:(SEL)origSel withMethod:(SEL)altSel {
    Method origMethod = class_getInstanceMethod(self, origSel);
    Method altMethod = class_getInstanceMethod(self, altSel);
    if (!origMethod || !altMethod) {
        return NO;
    }
    class_addMethod(self,
                    origSel,
                    class_getMethodImplementation(self, origSel),
                    method_getTypeEncoding(origMethod));
    class_addMethod(self,
                    altSel,
                    class_getMethodImplementation(self, altSel),
                    method_getTypeEncoding(altMethod));
    method_exchangeImplementations(class_getInstanceMethod(self, origSel),
                                   class_getInstanceMethod(self, altSel));
    return YES;
}

+ (BOOL)les_swizzleClassMethod:(SEL)origSel withMethod:(SEL)altSel {
    return [object_getClass((id)self) les_swizzleMethod:origSel withMethod:altSel];
}

@end

@interface NSString (LocalizedEngine)

@end

@implementation NSString(LocalizedEngine)

-(CGRect)le_boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context{
    return [LocalizedString(self) le_boundingRectWithSize:size options:options attributes:attributes context:context];
}

- (CGSize)le_sizeWithAttributes:(nullable NSDictionary<NSString *, id> *)attrs{
    return [LocalizedString(self) le_sizeWithAttributes:attrs];
}
@end

@interface UILabel (LocalizedEngine)

@end

@implementation UILabel(LocalizedEngine)

-(void)le_setText:(NSString *)text{
    [self le_setText:LocalizedString(text)];
}

@end

@interface UITabBarItem (LocalizedEngine)

@end
@implementation UITabBarItem (LocalizedEngine)

-(void)le_setTitle:(NSString *)title{
    [self le_setTitle:LocalizedString(title)];
}

@end

@interface UIViewController (LocalizedEngine)

@end
@implementation UIViewController (LocalizedEngine)

-(void)le_setTitle:(NSString *)title{
    [self le_setTitle:LocalizedString(title)];
}

@end

@interface UIButton (LocalizedEngine)

@end
@implementation UIButton (LocalizedEngine)

-(void)le_setTitle:(NSString *)title forState:(UIControlState)state{
    [self le_setTitle:LocalizedString(title) forState:state];
}

@end

@implementation LocalizedEngine

+(void)startEngine{
    [[UILabel class] les_swizzleMethod:@selector(setText:) withMethod:@selector(le_setText:)];
    [[UITabBarItem class] les_swizzleMethod:@selector(setTitle:) withMethod:@selector(le_setTitle:)];
    [[UIViewController class] les_swizzleMethod:@selector(setTitle:) withMethod:@selector(le_setTitle:)];
    [[UIButton class] les_swizzleMethod:@selector(setTitle:forState:) withMethod:@selector(le_setTitle:forState:)];
    [[NSString class] les_swizzleMethod:@selector(boundingRectWithSize:options:attributes:context:) withMethod:@selector(le_boundingRectWithSize:options:attributes:context:)];
    [[NSString class] les_swizzleMethod:@selector(sizeWithAttributes:) withMethod:@selector(le_sizeWithAttributes:)];


}

@end

调用只需要一句话
[LocalizedEngine startEngine];
其实只对UILabel做一次全局的文本就都被替换了,另一方面就是NSString对可变宽高的处理,这两个就已经解决了大部分需求,只不过后来发现系统控件在传递文本时做了布局的自适应,所以就有了UITabBarItem UIButton UIViewController的扩展,
根据自己APP情况适当调整即可,包括NSAttributedString 细化出来这些估计也不会超过200行,上边放出的是初版,.m总共100行冒头,轻轻松松省去慢慢找位置加,有人找你做本地化,从此只需要做好string对照表即可,让人按格式给你。
这只是利用AOP这种面向切面开发的思想解决问题的实例,同样的道理,风格扩展,日志,crash防御都能很好的独立且省事的完成。
后续还将放一篇AOPLogger的讲讲

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容