IOS本地化应用

BK项目已完成7788,在项目的后期需要被翻译成多国语言版。为了适应全球多个国家使用多个存储。

应用本地化是分别对字符串、图片和 xib 或 storyboard 文件本地化,而传统的做法是对 xib 上的字符串(包含UILabel和UIButton、UITextField等)关联一个变量,通过NSLocalizedString这个函数去查找 Localizeable .strings 文件里的key值进行本地化操作,或者是生成同一个xib文件的不同语言版本号。如 MainVC.xib(German) 和 MainVC.xib(English)。但这样做未免过于繁杂,像人们常说的 tedious and useless.


还是先介绍一下本地化的一般流程:

                                         

(1)伪本地化伪本地化是将字符串本地化为无意义语言的过程。

即将须要翻译的字符串替换成其它如果已经是翻译过的“译文”,能够用谷歌翻译替换一下或者是将全部元音字母替换成x。比如:“Press here to continue” 会变成 “Prxss hxrx tx cxntxnxx”。这样做的目的是为了尽早发现问题。

(2)冻结UI  在应用开发的周期中必需要有一个明白的时间点来冻结UI。在此之后要坚决杜绝会影响本地化的资源变更。nib 文件能够在XCode中锁定。以防止改动可本地化的属性、不可本地化的属性或者是全部属性,如图所看到的。然后将需要翻译的文本发给翻译人员或者是本地化服务提供商去翻译即可了。

                                             

(3)本地化将资源发给本地化服务提供商之后,他们会发回翻译完毕的文件。依据翻译的文本进行本地化工作。

(4)版本号控制用版本号控制系统记录下你的每一次变更。

(5)測试不用怎么说,必需要的步骤。

(6a)合并逻辑变更逻辑变更一般不会影响到nib文件和本地化的工作。多人协作的项目还是须要合并一些变更的逻辑的。

(6b)本地化变更假设你做了一些本地化变更,比方改变了已本地化的文本,那么就须要从头開始这个过程。并将这些变更发给本地化人员。能够重用之前的字符串翻译,这么做会大大提高效率,但仍然非常麻烦。所以,应尽量避免在开发后期引入这类变更。

应用本地化的文章之前已经就有非常多大牛写过了。这里就不在赘述了,直接贴出本人读过的认为还不错的文章:

1、MJ 的应用程序本地化,2013年写的,对于XCode5,有些操作界面已经不一样了,但思想是不变的。

2、IOS应用国际化教程(2014版),这个比較新,并且是使用 storyboard 的。

3、RAYWENDERLICH 上的 Internationalization Tutorial for iOS [2014 Edition] 这上面的文章都非常不错,非常值得一读,强烈推荐。

另外。重点是要讲我在 github 上找到的一个类,很棒,优雅的代码一直感动到我眼泪哗哗直流~~

这是github上的项目地址:HERE ,假设有找到很多其它更好的优秀代码,请知会一声。

就像作者所说的那样:

       

       

下面是OHAutoNIBi18n.m类。做了一下小改动,在不改变 frame 的情况下。对 UILabel、UIButton、UITextField 的字体大小做了一下自适应。

//
//  OHAutoNIBi18n.m
//
//  Created by Olivier on 03/11/10.
//  Copyright 2010 FoodReporter. All rights reserved.
//#import <objc/runtime.h>
#import <UIKit/UIKit.h>static inline NSString* localizedString(NSString* aString);static inline void localizeUIBarButtonItem(UIBarButtonItem* bbi);
static inline void localizeUIBarItem(UIBarItem* bi);
static inline void localizeUIButton(UIButton* btn);
static inline void localizeUILabel(UILabel* lbl);
static inline void localizeUINavigationItem(UINavigationItem* ni);
static inline void localizeUISearchBar(UISearchBar* sb);
static inline void localizeUISegmentedControl(UISegmentedControl* sc);
static inline void localizeUITextField(UITextField* tf);
static inline void localizeUITextView(UITextView* tv);
static inline void localizeUIViewController(UIViewController* vc);// ------------------------------------------------------------------------------------------------@interface NSObject(OHAutoNIBi18n)
-(void)localizeNibObject;
@end@implementation NSObject(OHAutoNIBi18n)#define LocalizeIfClass(Cls) if ([self isKindOfClass:[Cls class]]) localize##Cls((Cls*)self)
-(void)localizeNibObject
{LocalizeIfClass(UIBarButtonItem);else LocalizeIfClass(UIBarItem);else LocalizeIfClass(UIButton);else LocalizeIfClass(UILabel);else LocalizeIfClass(UINavigationItem);else LocalizeIfClass(UISearchBar);else LocalizeIfClass(UISegmentedControl);else LocalizeIfClass(UITextField);else LocalizeIfClass(UITextView);else LocalizeIfClass(UIViewController);if (self.isAccessibilityElement == YES){self.accessibilityLabel = localizedString(self.accessibilityLabel);self.accessibilityHint = localizedString(self.accessibilityHint);}// Call the original awakeFromNib method[self localizeNibObject]; // this actually calls the original awakeFromNib (and not localizeNibObject) because we did some method swizzling
}+(void)load
{// Autoload : swizzle -awakeFromNib with -localizeNibObject as soon as the app (and thus this class) is loadedMethod localizeNibObject = class_getInstanceMethod([NSObject class], @selector(localizeNibObject));Method awakeFromNib = class_getInstanceMethod([NSObject class], @selector(awakeFromNib));method_exchangeImplementations(awakeFromNib, localizeNibObject);
}@end/static inline NSString* localizedString(NSString* aString)
{if (aString == nil || [aString length] == 0)return aString;// Don't translate strings starting with a digitif ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[aString characterAtIndex:0]])return aString;#if OHAutoNIBi18n_DEBUG
#warning Debug mode for i18n is activestatic NSString* const kNoTranslation = @"$!";NSString* tr = [[NSBundle mainBundle] localizedStringForKey:aString value:kNoTranslation table:nil];if ([tr isEqualToString:kNoTranslation]){if ([aString hasPrefix:@"."]){// strings in XIB starting with '.' are typically used as temporary placeholder for design// and will be replaced by code later, so don't warn about themreturn aString;}NSLog(@"No translation for string '%@'",aString);tr = [NSString stringWithFormat:@"$%@$",aString];}return tr;
#elsereturn [[NSBundle mainBundle] localizedStringForKey:aString value:nil table:nil];
#endif
}// ------------------------------------------------------------------------------------------------static inline void localizeUIBarButtonItem(UIBarButtonItem* bbi) {localizeUIBarItem(bbi); /* inheritence */NSMutableSet* locTitles = [[NSMutableSet alloc] initWithCapacity:[bbi.possibleTitles count]];for(NSString* str in bbi.possibleTitles) {[locTitles addObject:localizedString(str)];}bbi.possibleTitles = [NSSet setWithSet:locTitles];
#if ! __has_feature(objc_arc)[locTitles release];
#endif
}static inline void localizeUIBarItem(UIBarItem* bi) {bi.title = localizedString(bi.title);
}static inline void localizeUIButton(UIButton* btn) {NSString* title[4] = {[btn titleForState:UIControlStateNormal],[btn titleForState:UIControlStateHighlighted],[btn titleForState:UIControlStateDisabled],[btn titleForState:UIControlStateSelected]};[btn.titleLabel setAdjustsFontSizeToFitWidth:YES];[btn setTitle:localizedString(title[0]) forState:UIControlStateNormal];if (title[1] == [btn titleForState:UIControlStateHighlighted])[btn setTitle:localizedString(title[1]) forState:UIControlStateHighlighted];if (title[2] == [btn titleForState:UIControlStateDisabled])[btn setTitle:localizedString(title[2]) forState:UIControlStateDisabled];if (title[3] == [btn titleForState:UIControlStateSelected])[btn setTitle:localizedString(title[3]) forState:UIControlStateSelected];
}static inline void localizeUILabel(UILabel* lbl) {lbl.adjustsFontSizeToFitWidth = YES;
//    lbl.minimumScaleFactor = 6.0f;lbl.text = localizedString(lbl.text);
}static inline void localizeUINavigationItem(UINavigationItem* ni) {ni.title = localizedString(ni.title);ni.prompt = localizedString(ni.prompt);
}static inline void localizeUISearchBar(UISearchBar* sb) {sb.placeholder = localizedString(sb.placeholder);sb.prompt = localizedString(sb.prompt);sb.text = localizedString(sb.text);NSMutableArray* locScopesTitles = [[NSMutableArray alloc] initWithCapacity:[sb.scopeButtonTitles count]];for(NSString* str in sb.scopeButtonTitles) {[locScopesTitles addObject:localizedString(str)];}sb.scopeButtonTitles = [NSArray arrayWithArray:locScopesTitles];
#if ! __has_feature(objc_arc)[locScopesTitles release];
#endif
}static inline void localizeUISegmentedControl(UISegmentedControl* sc) {NSUInteger n = sc.numberOfSegments;for(NSUInteger idx = 0; idx<n; ++idx) {[sc setTitle:localizedString([sc titleForSegmentAtIndex:idx]) forSegmentAtIndex:idx];}
}static inline void localizeUITextField(UITextField* tf) {tf.adjustsFontSizeToFitWidth = YES;tf.text = localizedString(tf.text);tf.placeholder = localizedString(tf.placeholder);
}static inline void localizeUITextView(UITextView* tv) {tv.text = localizedString(tv.text);
}static inline void localizeUIViewController(UIViewController* vc) {vc.title = localizedString(vc.title);
}

tips:本地化的时候还须要注意:

1、别忘了从右向左读的语言。

2、不要随便如果逗号就是千位分隔符以及句点就是小数点。在不同的语言中可能会有不同。

3、注意数字和日期的格式化(输入和输出都须要进行格式化)。

至此,,应用本地化的事儿就简单多了,剩下的事情就交给翻译人员去吧~


參考文章:

Apple官方文档:Localizing your APP

Apple官方文档:Internationalize Your App

Apple官方文档: Data Formatting Guide

Apple官方文档: Internationalization Programming Topics

Apple官方文档: Internationalization and Localization

本地化协作工具:https://www.transifex.com/product/

                            https://crowdin.com/



版权声明:本文博客原创文章,博客,未经同意,不得转载。

转载于:https://www.cnblogs.com/yxwkf/p/4615096.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低轨通信卫星: 开启 6G 通信时代,带动千亿规模市场

来源&#xff1a;中国银河证券摘要&#xff1a;“6G5G卫星网络”&#xff0c;卫星通信应用前景广阔。2017年11月&#xff0c;英国电信集团(BT)首席网络架构师NeilMcRae对6G通信进行了展望&#xff0c;他认为6G将是“5G卫星网络”&#xff0c;在5G的基础上集成卫星网络来实现全球…

电离层色散效应误差补偿——基于最大对比度自聚焦算法(总结)

电离层色散效应严重影响星载SAR成像质量&#xff0c;为提升P波段星载SAR图像质量&#xff0c;必须研究相应的补偿技术&#xff0c;从而使得其更好的应用在军事和民用上。 目录一、引言二、最大对比度自聚焦算法原理三、最大对比度自聚焦算法流程图四、补偿方法性能分析一、引言…

波士顿动力机器狗量产版首次亮相:先造100台,能当警犬能工地巡逻

来源&#xff1a;量子位摘要&#xff1a;波士顿动力的机器狗Spot Mini终于要量产了&#xff01;在科技媒体TechCrunch举办的“机器人AI”讨论会上&#xff0c;波士顿动力CEO Marc Raibert首次展示了它的量产版&#xff0c;还说今年7月或8月先量产100台。至于价格嘛&#xff0c;…

[MATLAB]中meshgrid函数的用法与实践(学习笔记)

今天在看点目标成像仿真程序的时候&#xff0c;看到了meshgrid函数&#xff0c;看了matlab的帮助文档后理解了一点&#xff0c;特此记录学习过程。 目录一、meshgrid函数二、举例验证三、创建二维网格绘制曲面图四、总结五、meshgrid函数源代码&#xff08;仅供参考&#xff09…

死猪脑”能复活吗?---评美国耶鲁大学医学院实验研究

来源&#xff1a;科学网博客4月17日&#xff0c;英国《自然》杂志刊发了科学家对于“复活”死猪脑的尝试&#xff1a;美国耶鲁大学医学院的研究团队将已经死亡4小时的猪脑接入新开发的BrainEX体外灌注系统&#xff0c;用正常体温下的模拟脉动血流进行灌注。6个小时灌注期内&…

Android开发(六)——组件颜色Selector(Selector与Shape的基本用法 )

andorid控件改变状态时改变颜色&#xff0c;使用selector。 <?xml version"1.0" encoding"utf-8" ?> <selector xmlns:android"http://schemas.android.com/apk/res/android"><!-- 默认时的背景图片--><item android:dra…

22页PPT告诉你5G产业最新投资机会!

来源&#xff1a;全球物联网观察随着5G与下游产业联动和协作相继深入&#xff0c;十万亿级规模5G大生态终将形成。5G产业链将推动四大变革&#xff1a;软件化、超高频大宽带、物联网化、高集成度。同时&#xff0c;5G也将成就边缘计算&#xff0c;进而推动云计算市场加速发展。…

报告解读 | 实现智能制造的五大关键环节和四大赋能路径

来源&#xff1a;阿里研究院近年来&#xff0c;随着大数据、云计算、人工智能、工业互联网等技术的迅速发展&#xff0c;数字化技术被广泛应用于经济的各个环节&#xff0c;推动了新消费时代的到来。个性化、定制化的消费观越来越普遍&#xff0c;重塑了生产者和消费者之间的关…

[转载] 一致性哈希

转载自http://www.jiacheo.org/blog/174 学习分布式, 一致性哈希是最最基础的知识, 所以要理解好. 那什么是一致性哈希呢?(what) 百度百科 上的解释很专业术语. 要一句话定义貌似也有难度: 一致性哈希算法是在哈希算法基础上&#xff0c;提出的在动态变化的分布式环境中&#…

NB-IoT,你真是太让我失望了

来源&#xff1a;EET电子工程专辑摘要&#xff1a;根据IHS Markit预测&#xff0c;2019年&#xff0c;在所有低功耗广域网公用网络中&#xff0c;超过40%都有望使用基于LoRa的设备&#xff0c;这意味着LoRa有望在今年成为主导型的LPWAN解决方案。那么“老对手”NB-IoT呢?“NB-…

深度学习详解

来源&#xff1a;传感器技术人工智能&#xff0c;就像长生不老和星际漫游一样&#xff0c;是人类最美好的梦想之一。虽然计算机技术已经取得了长足的进步&#xff0c;但是到目前为止&#xff0c;还没有一台电脑能产生“自我”的意识。但是自 2006 年以来&#xff0c;机器学习领…

Nature今发表脑机接口领域重大突破:

来源&#xff1a;学术经纬摘要&#xff1a;将计算机连通人脑&#xff0c;直接读取意识&#xff0c;这不是科幻。顶尖学术期刊《自然》刚刚在线发表的一项工作就在脑机接口领域向前迈出了一大步。加州大学旧金山分校&#xff08;UCSF&#xff09;的神经外科学家Edward Chang教授…

2019版中国数字经济发展与就业白皮书

未来智能实验室是人工智能学家与科学院相关机构联合成立的人工智能&#xff0c;互联网和脑科学交叉研究机构。未来智能实验室的主要工作包括&#xff1a;建立AI智能系统智商评测体系&#xff0c;开展世界人工智能智商评测&#xff1b;开展互联网&#xff08;城市&#xff09;云…

深入卷积神经网络背后的数学原理

来源&#xff1a;AI科技大本营摘要&#xff1a;在计算机神经视觉技术的发展过程中&#xff0c;卷积神经网络成为了其中的重要组成部分&#xff0c;本文对卷积神经网络的数学原理进行了介绍。文章包括四个主要内容&#xff1a;卷积、卷积层、池化层以及卷积神经网络中的反向传播…

Linux学习之如何在物理机上安装Linux发行版

Linux学习之如何在物理机上安装Linux发行版 第一步&#xff1a;制作系统安装盘 准备一个至少8GB的空白U盘。下载启动盘制作工具Rufus&#xff0c;下载链接&#xff1a;https://pan.baidu.com/s/1CU8oZJVyCgdwETI2VxJwxA 提取码&#xff1a;gwi1下载Linux发行版安装镜像&#…

jQuery Easy UI Accordion(可伸缩的面板)包

Accordion 可伸缩的面板组件。基于panel,示为以下的比率&#xff1a; <!doctype html> <html lang"en"><head><meta charset"UTF-8"><script type"text/javascript" src"easyui/jquery.min.js"></sc…

Linux学习之ARM开发板连接ubuntu18.04LTS及NFS相关配置

Linux学习之ARM开发板连接ubuntu18.04LTS及NFS相关配置 第一步&#xff1a;在PC机安装Ubuntu18.04LTS 具体安装步骤参见上一篇文章 第二步&#xff1a;安装arm-linux-gcc交叉编译环境 在终端中执行sudo mkdir /forlinx,新建名为forlinx的文件夹&#xff08;文件夹名可任意&…

报告解读 | 智能技术“核聚变”催生智能经济,将拉动十万亿市场

来源&#xff1a;阿里研究院从IT时代、互联网到智能2019年政府工作报告&#xff0c;正式提出了“智能”战略&#xff1a;“深化大数据、人工智能等研发应用。打造工业互联网平台&#xff0c;拓展‘智能’&#xff0c;为制造业转型升级赋能。”以5G、物联网、人工智能等技术为代…

Linux学习之云服务器搭建嵌入式Linux开发环境

Linux学习之云服务器搭建嵌入式Linux开发环境 第一步&#xff1a;购买云服务器 进入腾讯云官方网站腾讯云官方网站 选择云校园云校园 进入控制台 将云服务器系统设置为Ubuntu系统 使用Xshell6登录云服务器 使用Xftp6进行文件的上传与下载 在云服务器安装arm-linux-gcc…

JS中toFixed()方法的问题及解决方案

最近发现JS当中toFixed()方法存在一些问题&#xff0c;采用原生的Number对象的原型对象上的toFixed()方法时&#xff0c;规则并不是所谓的“四舍五入”或者是“四舍六入五成双”&#xff0c;所谓“四舍六入五成双”&#xff0c;在百度百科上给的解释是&#xff1a;也即“4舍6入…