iOS语言本地化/国际化宝典

语言本地化,又叫做语言国际化。是指根据用户操作系统的语言设置,自动将应用程序的语言设置为和用户操作系统语言一致的语言。往往一些应用程序需要提供给多个国家的人群使用,或者一个国家有多种语言,这就要求应用程序所展示的文字、图片等信息,能够让讲不同语言的用户读懂、看懂。进而提出为同一个应用程序适配多种语言,也即是国际化。语言国际化之所以又叫做语言本地化,这是站在每个用户的角度而言的,是指能够让用户本地、本土人群能够看懂的语言信息,顾名思义,语言本地化。其实语言本地化 == 语言国际化!其实应用的国际化,大都是中/英文,本文以app中英文国际化为例子。本例子的app包含地图和地图导航。
本文将分如下8个主要章节一步一步讲解如何完全本地化一个App。
1.配置需要国际化的语言(国际化的准备工作)
2.App名称本地化
3.代码中字符串本地化
4.多人开发情况下的字符串本地化
5.图片本地化(两种方式两种方式)
6.查看/切换本地语言
7.地图本地化
8.导航本地化
手机系统语言设置(通用-设置-语言与地区-iPhone 语言-English英文):
这里写图片描述
这里写图片描述
(一)配置需要国际化的语言

配置需要国际化的语言,这也是国际化之前的准备工作,无论我们是国际化App名称、代码中的字符串、图片、还是storyboard和xib,都需要进行这一步的准备工作(一个项目中需要且仅需要配置一次)。

注意:你的应用以前可能只支持中文,应用启动的页面可能使用的是LaunchImage,没有配置Launch Screen。需要先配置Launch Screen,你才能在Localizations中配置多国语言。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
重新创建Launch Screen文件
这里写图片描述
这里写图片描述
这里写图片描述
国际化时你也要修改Target–>Info–>Localization native development region : China
若你不修改你使用第三方控件时显示的是部分国际化的页面,如:TZImagePickerController。
修改前:
修改前的配置
修改前的效果:
这里写图片描述
修改后:
这里写图片描述
修改后的效果:
这里写图片描述
当然你若想兼容ios7,等你配置了多国语言后,点击项目名称,选择 TARGETS,选择 General,找到 Launch Screen File, 将该项清空并回车(默认的是 LaunchScreen.storyboard)。

针对IOS7,苹果提供了LaunchImage来实现欢迎界面,开发的时候只需要将设计好对应尺寸的图片拖到对应的状态的位置即可。
IOS8出现之后,苹果推出了LaunchScreen.xib来做欢迎界面,如果还想通过LaunchImage来做欢迎界面,完美适配IOS7和IOS8。
若你的应用想兼容ios7.0系统,你只能使用LaunchImage,不能使用LaunchScreen。
如果你想要动态修改启动页面图LaunchImage,抱歉!根据苹果的用户交互指引,该页面是在程序加载时显示的,不建议动态修改.
如果真想动态修改启动页面,启动页面是固定的名字,可以在程序执行之后强制把页面替换掉,不过这样APP可能会被拒.
为了兼容iOS7,最好不要在启动页面增加需要修改的信息,如版本号。不然版本号变更时还要重新切图。所以大部分应用的启动页面都没有版本号等需要频繁修改的信息。
这篇文章《iOS 启动图国际化的两种可行方案》https://sanwen8.cn/p/488n1u7.html
按照它的操作,根本不能国际化。第一种方案的结果是屏幕根本无法适配屏幕,启动页面显示的是icon放大图。第二种方案,显示的是配置的那个LaunchScreen.storyboard。切换语言在真机上一点效果都没有。
从测试过替换app的本地启动图,使下次使用和手机系统语言一致的启动图。结果是没有影响。原因是app的启动图是以字符流的形式和代码放在一起不是按目录存储的,所以根本无法实际修改。所以想通过修改本地启动图的方案泡汤了。
我又尝试用Launch Screen上放一个UIImageView,给它的image配置一个国际化的图片,结果应用在切换语言后,仍旧显示中文或英文启动图,根本不根据手机系统语言来切换。这个方案也泡汤了。
基本上启动图国际化暂时处于无解状态,看来还是从设计上避免启动页面出现需要国际化的文字才是唯一王道。
(二)应用名称本地化/国际化
应用名称本地化,是指同一个App的名称,在不同的语言环境下(也就是手机设备的语言设置)显示不同的名称。比如,微信在简体中文环境下App名称显示为“户外俱乐部”,在英语环境下显示为“outdoorClub”。下面就开始进行应用名称本地化。

选中Info.plist,按下键盘上的command + N,选择Strings File(iOS->Resource->Strings File)

这里写图片描述
文件名字命名为InfoPlist,且必须是这个名字:
这里写图片描述
点击create后,Xcode左侧导航列表就会出现名为InfoPlist.strings的文件.
选中InfoPlist.strings,在Xcode的File inspection(Xcode右侧文件检查器)中点击Localize,目的是选择我们需要本地化的语言,如下图:
这里写图片描述
注意:在点击Localize之前,一定要保证我们已经添加了需要本地化的语言,也就是上面配置需要国际化的语言那一步(步骤:project->Info->Localizations,然后点击”+”,添加需要国际化/本地化的语言)。
点击Localize后,会弹出一个对话框,展开对话框列表,发现下拉列表所展示的语言正是我们在上面配置的需要国际化的语言,选择我们需要本地化的语言,然后点击对话框的Localize按钮,如下图:
这里写图片描述
注意:如果我们没有在 PROJECT 中配置需要国际化的语言(project->Info->Localizations,然后点击”+”),上图下拉列表中将只会出现”Base”和”English”选项,English语言是系统默认的语言,其他需要国际化的语言(例如中文简体)必须通过上面的配置本地化语言那一步手动添加。
然后我们发现Xcode右侧的File inspection变成了下图的样式:
勾选Chinese(zh-Hans)、English。不要勾选Base,这个Base没有什么鸟用,并不是想象的默认语言。
此时,Xcode左侧的InfoPlist.stirings左侧多了一个箭头,点击箭头可以展开,如下图所这里写图片描述
这里写图片描述
从上图可以看出,InfoPlist.strings文件下包含了Base、Chinese(zh-Hans)、English这2种语言和一个默认语言的文件。
原理:程序启动时,会根据操作系统设置的语言,自动加载InfoPlist.strings文件下对应的语言文件,然后显示应用程序的名字。

接下来,我们分别用不同的语言给InfoPlist.strings下的文件设置对应的名字。
(1)在InfoPlist.strings(english)中加入如下代码:

// Localizable App Name是App在英语环境环境下显示的名称
CFBundleDisplayName = “OutdoorClub”;
备注:CFBundleDisplayName可以使用双引号,也可以不使用双引号!
(2)在InfoPlist.strings(Base)中加入如下代码:
CFBundleDisplayName = “OutdoorClub”;
(3)在InfoPlist.strings(Chinese(Simplified))中加入如下代码:
CFBundleDisplayName = “户外俱乐部”;
注意:千万别把Info.plist文件也本地化了,不然编译时会报找不到Info.plist,我也没有找到怎么修改过来,我折腾了半天,最终还是从其它项目拷贝过来这个文件,才搞定它。
修改手机语言为English。App名称如下图:
这里写图片描述
修改手机系统语言为简体中文(Chines,Simplified)。App名称如下图:
这里写图片描述
至此,本地化App名称已经演示完毕,其步骤就是:
1.在Project的设置中通过点击”+”添加需要本地化的语言。
2.然后在Xcode右侧的File inspection中点击Localize,选中需要本地化App名称的语言。
3.最后在每个语言对应的文件中以key = value(CFBundleDisplayName = “App名称”;);的形式设置App的名称。
(三)代码中字符串的本地化

所谓字符串本地化,就是指App内的字符串在不同的语言环境下显示不同的内容。比如,”主页”这个字符串在中文语言环境下显示“主页”,在英语环境下显示“home”。下面就开始进行字符串本地化。
其实字符本地化和App名称本地化过程如出一辙,只是创建的文件名成不一样(连同后缀一起,文件名必须是Localizable.strings),其他步骤完全相同。为了能够让大家彻底了解,此处还是会把步骤一一贴出来。

和应用名称本地化一样,首先需要command + N,选择iOS -> Resource -> Strings File
文件名必须命名为Localizable
备注:因本人电脑是隐藏文件后缀名,所以不会自动补全.strings后缀名。
这里写图片描述
文件创建成功,查看Xcode左侧导航列表,发现多了一个名为Localizable.strings的文件。
选中Localizable.strings文件,在Xcode的File inspection中点击Localize,目的是选择我们需要本地化的语言(和本地化App名称同理):
这里写图片描述
依次选择English->Localize,如下图:
这里写图片描述
这里写图片描述
然后我们发现Xcode右侧的File inspection变成了下图的样式:
然后勾选English、Chinese(zh-Hans),不要勾选Base,这个Base没有什么鸟用,并不是想象的默认语言。如下图:
此时,Xcode左侧的Localizable.stirings左侧多了一个箭头,展开后,如下图所示:
这里写图片描述
然后我们只需要在Localizable.strings下对应的文件中,分别以Key-Value的形式,为代码中每一个需要本地化的字符串赋值,如下图:
这里写图片描述
这里写图片描述
本地化代码中的字符串,如下图:
这里写图片描述
我们只需要使用Foundation框架自带的NSLocalizedString(key, comment)这个宏根据Key获取对应的字符串,然后赋值给代码中的字符串。
// NSLocalizedString(key, comment) 本质
// NSlocalizeString 第一个参数是内容,根据第一个参数去对应语言的文件中取对应的字符串,第二个参数将会转化为字符串文件里的注释,可以传nil,也可以传空字符串@”“。

define NSLocalizedString(key, comment) [[NSBundle mainBundle] localizedStringForKey:(key) value:@”” table:nil]

不同语言环境下运行效果,如下图:
简体中文环境下:
这里写图片描述
英语环境下:
这里写图片描述
2017-04-07 13:45:45.131114+0800 OutdoorClub[6697:1901911] 当前语言:en-CN
如此一来,我们就实现了代码中字符串的本地化。
技巧
其实,我们不需要给Localizable.strings(English)文件添加Key-Value。原因如下:系统根据某个key去获取对应的字符串时,如果没有找到,那么就会以key作为value返回。所以如果我们在Localizable.strings(English)文件中没有添加 “RecordFootMarkTabRightTitle” = “留下足迹”或添加的是”FootMarkTabRightTitle” = “留下足迹”;那么在english环境下右导航按钮最终显示的title会是RecordFootMarkTabRightTitle。如下图:
这里写图片描述

切换语言无需在模拟器中设置,只需要在Xcode中进行如下设置: Edit->Scheme->Run->Arguments Passed On Launch ->-AppleLanguages (语言代码)。例如,我们模拟器此时虽然是韩语,如果通过上述步骤设置为zh-Hans,那么语言环境将会变为汉语,如下图:
这里写图片描述
这里写图片描述
如此一来,切换语言变得更加简单,无需在模拟器的设置中进行繁琐的语言切换。
(四)多人开发情况下的字符串本地化
项目开发中,独立开发的还是少数。经常会有多人开发的情况,这种情况,如果多人同时操作本地化文件,极有可能会存在冲突。另一方面,我们又不希望自己的本地化文件受到对方的污染,也就是说,我们不希望对方操作我们的本地化文件。但是上面介绍的代码中字符串的本地化是使用的是默认的文件名”Localizable”,因为启动程序时,系统将根据语言加载相应的文件得到其对应的字符串文件,这个字符串可以通过系统将NSLocalizedString中的宏生成名为“Localizable.strings”的文件。那么如何让系统加载我们自己命名的本地化文件而非系统默认的Localizable.strings呢?这就是 NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)的用处。
也就是说,如果你的strings文件名字不是Localizable而是自定义的话,如VVS.strings,那么你就得使用NSLocalizedStringFromTable这个宏来读取本地化字符串。这个功能是重点常用功能,需要把以前的步骤重新说明下。

// key:系统根据key取字符串
// tbl:自定义strings文件的名字
// comment:可以不传
    NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)

基础框架UITabBarController及UXTabBarItem等为一个人写的,具体的页面为另一个人写的。基础框架部分可以使用NSLocalizedString或NSLocalizedStringFromTable,具体页面使用NSLocalizedStringFromTable。
首先需要command + N,选择iOS -> Resource -> Strings File,文件名随便写,如我把它命名为LocalizedStringFromTable。如下图:
这里写图片描述
首先选择中文,别选Base,它没有用。
这里写图片描述
中文版本的代码
这里写图片描述
英文版本的代码
这里写图片描述
使用地方的代码
这里写图片描述
简体中文环境下:
这里写图片描述
英语环境下:
这里写图片描述
如此一来,我们就可以挣脱别人的strings文件和系统默认的Localizable.strings文件,自己另起炉灶。

(五)图片本地化

本地化图片,有两种方式,第一种方式和本地化代码中的字符串一样,通过NSLocalizedString(key,comment)来获取相应的字符串,然后根据这个字符串再获取图片。

方式一

// annotationView.image = [UIImage imageNamed:@”common_icon_map_departure”];
annotationView.image = [UIImage imageNamed:NSLocalizedStringFromTable(@”StartPointIcon”,@”LocalizedStringFromTable”, nil)];
方式二
首先需要添加需要本地化的语言,具体步骤参考第一章配置需要国际化的语言。因为我演示的demo中在本地化App名称时已经添加了需要国际化的语言。所以不需要再设置。
将图片拖入工程中,例如“c01_icon_circle@2x.png”,然后选中c01_icon_circle@2x.png,展开Xcode右侧的file Inspection,点击Localize,如下图:
这里写图片描述
在Localization中勾选English
然后,右击c01_icon_circle@2x.png->show in Finder,我们发现在zh-Hans.Iproj和en.lproj文件中都多了一个名为c01_icon_circle@2x.png的图片,如下图:
替换这两个文件夹下的图片,要保证替换后的图片文件名和原来的文件名一致。至于你想两个都替换还是只替换一个图片自己决定。
然后发现,icon.png左边出现了一个可以展开的三角形。如下图:
这里写图片描述
注意:二倍图和三倍图都要国际化。当你对二倍图进行了国际化,没有对三倍图国际化,你使用iphone5s时它使用的是三倍图的图片,当时我测试时找了半天,才发现这个问题。
这里写图片描述
然后控制器中添加如下代码:

annotationView.image = [UIImage imageNamed:@"c01_icon_circle"];

english环境下运行效果如下:
这里写图片描述
中文环境改下运行效果如下:
这里写图片描述
虽然我们不提倡使用XIB和storyboard进行页面布局,我们也顺便说一下它们的图片国际化。在xib的文件中随便增加一个UIImageView,也不进行布局了。注意:设置图片的Image的名称是要带”.png”后缀,不然你看到的是一个大问号,不过不影响运行。
图片的Image的名称要不带”.png”后缀的效果
这里写图片描述
图片的Image的名称带”.png”后缀的效果
这里写图片描述
中文环境改下运行效果如下:
这里写图片描述
英语环境下:
这里写图片描述

其他语言环境,例如法语、中文繁体、韩语,操作步骤完全和上面相同。都是在对应的.Iproj文件夹下添加同名的图片,然后把图片拖放到Xcode中,不再赘述。
由于我们的应用都是使用的Assets.xcassets(看到的文件列表个数少一倍,二倍图和三倍图在一起,一倍图已经没有应用还适配了),无法用第二种图片国际化方案。
简述:第一种方案(换图片名称)安全快捷,能快捷适配二倍图和三倍图。
在软件设计时尽量别把文字放到图标上,若放上了文字,国际化时肯定要换图标了。当然有时候,有的场景不可避免的出现文字。如我们的一个按钮动画,按钮包括文字从正常变小然后逐渐恢复原状。这个按钮上有文字并且是圆形的。若对按钮不设置图片,设置圆角进行动画,你发现动画时按钮时呈矩形动画的,所以还是设置背景图片吧!这样的icon当然要国际化了。只要做到能避免就避免,真不能避免的就国际化就可以了。
这里写图片描述
icon图标的尺寸有58*58,80*80,87*87,120*120,180*180等5种尺寸类型。
启动页面的尺寸有640*960,640*1136,750*1134,1242*2208等4种尺寸类型。
photoshop把选中的图层替换为前景色快捷键:alt+delete,把选中的图层替换为后景色快捷键:cmmand+delete。
(六)查看/切换本地语言
原理:应用启动时,首先会读取NSUserDefaults中的key为AppleLanguages对应的value,该value是一个String数组,也就是说,我们访问这个名为AppleLanguages的key可以返回一个string数组,该数组存储着APP支持的语言列表,数组的第一项为APP当前默认的语言。

- (UIButton *)rightBtn
{
    if (!_rightBtn) {
        _rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _rightBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
        _rightBtn.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
        _rightBtn.titleLabel.font = YXFont(14.f);
        if(![[ODCCurrentPathLocationDataSingleObject sharedInstance] getCurrentOperationType])
        {
            [_rightBtn setTitle:NSLocalizedStringFromTable(@"RecordFootMarkTabRightTitle", @"LocalizedStringFromTable", nil) forState:UIControlStateNormal];
        }
        else
        {
            [_rightBtn setTitle:NSLocalizedStringFromTable(@"StoreFootMarkTabRightTitle",@"LocalizedStringFromTable", nil) forState:UIControlStateNormal];
        }
        [_rightBtn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
        _rightBtn.backgroundColor = [UIColor clearColor];
        [_rightBtn setTitleColor:[UIColor colorWithHexString:@"0X5C5C5C"] forState:UIControlStateNormal];
        NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
        NSString *currentLanguage = languages.firstObject;
        FLDDLogDebug(@"当前语言:%@",currentLanguage);
        //模拟器上的英语是"en",模拟器上的中文是"zh-Hant",真机上的都是以"en-"开头,以此类推汉语的前缀是"zh-Hant-",通过下面的方式可以适配语言族
        if(([currentLanguage hasPrefix:@"en-"]) || ([currentLanguage isEqualToString:@"en"]))
        {
            _rightBtn.frame = CGRectMake(0, 0, 120.f, 18.f);
        }
        else
        {
            _rightBtn.frame = CGRectMake(0, 0, 60.f, 18.f);
        }

        @weakify(self);
        [[_rightBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
            @strongify(self);
            [self processRightBtnHit];
        }];
    }
    return _rightBtn;
}

中文状态下打印日志:
这里写图片描述
英文状态下打印日志:
这里写图片描述

同理,既然我们可以通过AppleLanguages这个key从NSUserDefaults中取出语言数组,那么我们也可以给AppleLanguages这个key赋值来达到切换本地语言的效果,从此以后,我们就无需频繁的去模拟器的设置->通用->语言与地区 中切换语言。通过NSUserDefaults或单例可以设计出你自定义的语言国际化。

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 切换语言前
    NSArray *langArr1 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSString *language1 = langArr1.firstObject;
    NSLog(@"模拟器语言切换之前:%@",language1);

    // 切换语言
    NSArray *lans = @[@"en"];
    [[NSUserDefaults standardUserDefaults] setObject:lans forKey:@"AppleLanguages"];

    // 切换语言后
    NSArray *langArr2 = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"];
    NSString *language2 = langArr2.firstObject;
    NSLog(@"模拟器语言切换之后:%@",language2);
}
@end

(七)地图本地化
使用场景
如果app中需要支持国内、国外地图,则可以利用该示例,在app中同时集成高德和苹果地图,保证国内外地图均可使用。
可以根据地图中心点在国内、外自动提示是否切换地图。
核心类/接口
用到产品
iOS 地图 SDK iOS 定位 SDK Apple MapKit
核心类/接口
- (void)mapView:(UIView *)mapView regionDidChangeAnimated:(BOOL)animated;//响应地图区域变化,判断中心点
- (void)performSwitching;//执行切换
核心难点
1.在地图delegate内判断中心点是否在国内
- (void)mapView:(UIView *)mapView regionDidChangeAnimated:(BOOL)animated {
if(mapView.isHidden) {
return;
}

if(self.isSwitching) {
    self.isSwitching = NO;
    return;
}

if([mapView isKindOfClass:[MAMapView class]]) {
    if(!AMapDataAvailableForCoordinate(self.gaodeMapview.centerCoordinate)) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"是否切换到苹果地图显示" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alert show];
    }
} else {
    if(AMapDataAvailableForCoordinate(self.appleMapview.centerCoordinate)) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"是否切换到高德地图显示" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alert show];
    }
}

}

2.切换地图,主要同步region、中心点经纬度、旋转角度。目前不支持camera视角同步
/**
执行切换
*/
- (void)performSwitching {
self.isSwitching = YES;

[self.gaodeMapview setHidden:!self.gaodeMapview.isHidden];
[self.appleMapview setHidden:!self.appleMapview.isHidden];

if(!self.gaodeMapview.isHidden) {
    MACoordinateRegion region = [self MARegionForMKRegion:self.appleMapview.region];
    [self.gaodeMapview setRegion:region];

    self.gaodeMapview.centerCoordinate = self.appleMapview.centerCoordinate;

    [self.gaodeMapview setRotationDegree:self.appleMapview.camera.heading];
} else {
    MKCoordinateRegion region = [self MKRegionForMARegion:self.gaodeMapview.region];
    [self.appleMapview setRegion:region];

    self.appleMapview.centerCoordinate = self.gaodeMapview.centerCoordinate;

    [self.appleMapview.camera setHeading:self.gaodeMapview.rotationDegree];
}

}
Google Mapandroid版和IOS版的SDK都没有集成路径规划的相关API,若要实现,只能通过http链接请求URL,携带起点终点经纬度,得到返回集合,在地图中展示。
Google Directions API :https://developers.google.com/maps/documentation/directions/#Waypoints
Directions Service:https://developers.google.com/maps/documentation/javascript/directions#DirectionsRequests
Google地图的iOS研发者地址:
https://developers.google.com/maps/documentation/ios-sdk/
API 密钥管理地址:
https://console.developers.google.com/apis/credentials/key/93?project=my-project-1492762633484
Google地图iOS相关包
这里写图片描述
既然知道了地图本地化,那么来得正点的。
各位看官,既然看这篇文章,那么可能会有咱们国内的开发人员相做出像OICQ一样,可以在中国和国际上用的应用。可能有咱们中国程序员想在国外使用的基于LBS的APP和WEB服务器,而老外的人力成本高的吓人。中国又禁止使用Google Map。在国内使用Google Map肯定要翻墙了,只能用VPN了。注意VPN也是有区别的。有的VPN只能使用网页,不能使用Pods下载Goople Map的基础包。VPN一般又以美国的为主。大家买VPN时要小心了。我现在还是使用免费的VPN。由于是使用VPN跳转,网速就不敢恭维了,而且使用国内地图惯了程序猿,遇到Google Map会有很多水土不服,它还有很多坑,想在中国使用Google Map真的不容易。
首先要申请一个地图Key吧!地址:https://console.developers.google.com/apis/dashboard?project=main-analog-165612&hl=zh-cn&duration=PT1H。用户注册不用讲了吧!
这里写图片描述
申请Key成功后
这里写图片描述
注意:Google Map不是你申请了key,就可以使用的,不然会报400的错误。这个问题纠结了我一天多,我找了很久也没有找到答案,我试了很久才试出来。
错误信息:
ClientParametersRequest failed, 5 attempts remaining (0 vs 11). Error Domain=com.google.HTTPStatus Code=400 “(null)” UserInfo={data=<3c48544d 4c3e0a3c 48454144 3e0a3c54 49544c45 3e426164 20526571 75657374 3c2f5449 544c453e 0a3c2f48 4541443e 0a3c424f 44592042 47434f4c 4f523d22 23464646 46464622 20544558 543d2223 30303030 3030223e 0a3c4831 3e426164 20526571 75657374 3c2f4831 3e0a3c48 323e4572 726f7220 3430303c 2f48323e 0a3c2f42 4f44593e 0a3c2f48 544d4c3e 0a>}
解决方案:
申请了Key,要启用Key,启用过程如下图:
这里写图片描述

这里写图片描述

这里写图片描述
启动API成功
这里写图片描述
离开信息中心后再进入信息中心
这里写图片描述
按照官方文档,配置Podfile,在里面增加:

    pod 'GoogleMaps'
    pod 'GooglePlaces'

设置VPN下载地图包
这里写图片描述
在Podfile所在目录执行:
pod update
在AppDelegate.m里增加如下代码:

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [GMSServices provideAPIKey:@"key"]; //com.geely.ETPtaxiDriver

    return YES;
}

在页面中增加如下代码:

#import "ODCGoogleMapViewController.h"
#import <GoogleMaps/GoogleMaps.h>
@interface ODCGoogleMapViewController ()
@property (nonatomic, strong) GMSMapView *mapView;//地图
@end
@implementation ODCGoogleMapViewController
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if(self.mapView == nil)
    {
        GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:51.3
                                                                longitude:0.1
                                                                     zoom:6];
        GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
        mapView.myLocationEnabled = YES;
        self.view = mapView;
        self.mapView = mapView;
    }
    // Creates a marker in the center of the map.
    GMSMarker *marker = [[GMSMarker alloc] init];
    marker.position = CLLocationCoordinate2DMake(51.3, 0.1);
    marker.title = @"London";
    marker.snippet = @"the United Kingdom;";
    marker.map = self.mapView;
}

注意:若你的地图页面放在UXTabBarController里,并且不在第一个显示页面中,那么不能把地图加载放入viewDidLoad里面,不然加载不出来。
可能由于网络原因,应用启动后,首次加载,可能显示不出来,离开这个页面再进入可能就显示出来了。
模拟器显示出来的效果:
这里写图片描述
google map的demo下载地址:链接: https://pan.baidu.com/s/1dEHj0QH 密码: 69es

(八)导航本地化
科大讯飞语言设置:- (IFlySpeechSynthesizer *)iFlySpeechSynthesizer {
if (!_iFlySpeechSynthesizer) {
//1.创建合成对象
_iFlySpeechSynthesizer = [IFlySpeechSynthesizer sharedInstance];
_iFlySpeechSynthesizer.delegate = self;
//2.设置合成参数
//设置在线工作方式
[_iFlySpeechSynthesizer setParameter:[IFlySpeechConstant TYPE_CLOUD]
forKey:[IFlySpeechConstant ENGINE_TYPE]];
//音量,取值范围 0~100
[_iFlySpeechSynthesizer setParameter:@”100” forKey: [IFlySpeechConstant VOLUME]];
// 语速,取值范围 0~100
[_iFlySpeechSynthesizer setParameter:@”85” forKey:[IFlySpeechConstant SPEED]];
//发音人,默认为”xiaoyan”,可以设置的参数列表可参考“合成发音人列表”
[_iFlySpeechSynthesizer setParameter:@”xiaoyan” forKey: [IFlySpeechConstant VOICE_NAME]];
[_iFlySpeechSynthesizer setParameter:[IFlySpeechConstant LANGUAGE]
forKey:[IFlySpeechConstant LANGUAGE_ENGLISH]];
}
return _iFlySpeechSynthesizer;
}

从查到的资料发现google只支持页面或app导航不支持嵌入式导航,目前正在探索
if ( [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@”comgooglemaps://”]]){

  UIAlertAction *action = [UIAlertAction actionWithTitle:@”谷歌地图” style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

  NSString *urlString = [[NSString stringWithFormat:@”comgooglemaps://?x-source=%@&x-success=%@&saddr=&daddr=%f,%f&directionsmode=driving”,appName,urlScheme,coordinate.latitude, coordinate.longitude] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];

}];

  [alert addAction:action];

}

未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值