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 loaded
Method 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 digit
if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[aString characterAtIndex:0]])
return aString; #if OHAutoNIBi18n_DEBUG
#warning Debug mode for i18n is active
static 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 them
return aString;
}
NSLog(@"No translation for string '%@'",aString);
tr = [NSString stringWithFormat:@"$%@$",aString];
}
return tr;
#else
return [[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/

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

IOS本地化应用的更多相关文章

  1. iOS本地化

    本地化与相机中显示英文  工程PROJECT -> info ->Localizations 添加相应的国际化语言  一.当你发现相机中显示英文,可以通过它设置 添加一项“Localize ...

  2. [IOS]本地化

    我们在IOS开发应用中,会碰到做好的一个应用,如何趋向国际化,也就是说支持多种语言?下面我就来简单演示一下,用一个Demo来实现中文和英文的实现. 实现步骤: 1.本地化项目中xib的view 1.在 ...

  3. IOS本地化。

    1,项目名本地化 点击项目,蓝色图标->info 最下面+号,添加chinese本地化. Supporting Files->infoPlist.strings 下会有两个文件,有一个是设 ...

  4. iOS 本地化应用程序(NSLocalizedString)

    App本地化的需要不用讲大家也都明白,本文将介绍一种简单的方法来实现字符串的本地化. 在不考虑本地化的情况下,我们如果在代码中给一个Button定义title,一般会这样写: btn.titleLab ...

  5. iOS本地化应用程序

    因为使用的是xcode4,应用程序本地化的问题跟以前的版本还是有些不同,在网上找了些资料对于xcode4以上的版本资料还是相对较少,有些最后要通过手动创建文件,这样操作实在是太麻烦,所以经过一个下午的 ...

  6. ios本地化多语言支持

    右键 -> new file -> resources -> strings file 一定要命名为: Localizable.strings 点击这个文件 -> xocde ...

  7. Xcode5和6上新建工程如何本地化启动页面

    建议阅读本篇文章前先具备iOS本地化的基本知识,Google中搜索“iOS本地化”,有成片的教程~~ 最近有个app需要支持英语.简体中文.繁体中文,由于启动页面上有文字,所以也不得不做下本地化处理. ...

  8. Xcode4.5 本地化,多语言设置

    网上已有很多关于ios本地化的博客和资料,由于部分原作者使用的Xcode版本较早,4.5以后的版本已不再支持该方法,后来也没有更新,因此在此写一点学习资料分享出来.废话不多说.     ios本地化主 ...

  9. 最全的iOS数据存储方法

    目的 项目准备运用的Core Data进行本地数据存储,本来打算只写一下Core Data的,不过既然说到了数据存储,干脆来个数据存储基础大总结!本文将对以下几个模块进行叙述. 沙盒 Plist Pr ...

随机推荐

  1. ThinkPHP框架视图详细介绍 View 视图--模板(九)

    原文:ThinkPHP框架视图详细介绍 View 视图--模板(九) 视图也是ThinkPHP使用的核心部分: 一.模板的使用 a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主题文件夹/]和 ...

  2. 14.3.5.3 How to Minimize and Handle Deadlocks 如何减少和处理死锁

    14.3.5.3 How to Minimize and Handle Deadlocks 如何减少和处理死锁 这个章节建立关于死锁的概念信息,它解释如何组织数据库操作来减少死锁和随后的错误处理: D ...

  3. 图像编程学习笔记2——bmp位图平移

    以下文字内容copy于<<数字图像处理编程入门>>,code为自己实现,是win32控制台程序. 2.1 平移 平移(translation)变换大概是几何变换中最简单的一种了 ...

  4. 用gradle管理android项目出现的问题以及解决方法

    1.项目结构 最好是全部在root 项目配置 一个settings.gradle 一个build.gradle 2.多项目依赖 http://www.gradle.org/docs/current/u ...

  5. What is the difference between JRE,JVM and JDK?

    If you are a Java developer, it is very often that you think about understanding the JRE,JVM and JDK ...

  6. SICP 习题 (2.6) 解题总结:丘奇计数

    SICP 习题 2.6 讲的是丘奇计数,是习题2.4 和 2.5的延续. 这里大师们想提醒我们思考的是"数"究竟是什么,在计算机系统里能够怎样实现"数".准备好 ...

  7. Android Studio Gradle 添加.so 支持文件

    近期发展Android Wear 关注商品.官员Demo所有gradle 工程. 当然,我也用eclipse配置一个可行的环境. 问题来了,eclipse,android studio 开发 andr ...

  8. 基于Servlet、JSP、JDBC、MySQL的一个简单的用户注冊模块(附完整源代码)

    近期看老罗视频,做了一个简单的用户注冊系统.用户通过网页(JSP)输入用户名.真名和password,Servlet接收后通过JDBC将信息保存到MySQL中.尽管是个简单的不能再简单的东西,但麻雀虽 ...

  9. myeclipse10.7皴,出口解决war包时报“SECURITY ALERT: INTEGERITY CHECK ERROR”

    一.操作系统的环境是win7,64bit和32bit的操作系统我试过都OK 依照网上一些Crack破解程序步骤操作就能够完毕破解过程, 也能够到我的CSDN资源里下载文件包 myeclipse10.7 ...

  10. .Net 文本框实现内容提示(仿Google、Baidu)

    原文:.Net 文本框实现内容提示(仿Google.Baidu) 1.Demo下载: 文本框实现内容提示(仿Google.Baidu).rar 2.创建数据库.表(我用的sqlserver2008数据 ...