为了解决内置的iOS地图无法定位国外经纬度的缺陷,我决定尝试用Google的Api来实现地图定位。经过一番折腾,在iOS7(iPad mini)上顺利通过,可以定位国内、国外的地址,还有一个会跑的小人的动画(有一点小激动),但iOS5上却报了一大堆的连接符号的错误,先不管错误,后面再解决,先把我调试通过iOS7的过程说一下(貌似网上都没有人提供这方面的成功经验!)
1、在这个https://developers.google.com/maps/documentation/ios/intro网站下载最新的Google sdk,我用的是1.7.2,官方说法是“With the Google Maps SDK for iOS, you can build apps that target native 32-bit or 64-bit devices running iOS 6.0 and later”。(如果我要在iOS5上调试,是不是必须下载以前的版本的)
2、解压后有两个文件夹GoogleMaps.framework和GoogleMapsSDKDemos(这两个东西都非常重要)
3、新建一个Xcode5的项目,注意:xcode5下最好建一个空的项目,视图的显示通过新建ViewController来实现。记住该项目的Bundle Identifier,例如aa.bb
4、到前面的那个网址里申请Key(一个Key针对一个项目名),按照里面说的做就行了(前面选择所需的地图服务,只要免费的我都选),只要输入Bundle Identifier就可以生成一个40字节的Key,保存好。
5、前面网址里有较你怎么使用的示例,但会有一些不同。GoogleMaps.framework有三种,一个是含头文件的文件夹,一个是可执行文件52M,一个是framework只有23字节,名字都一样,文件夹名字的那个先放入你需要调试的框架下面,例如iOS7的就是/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks下(最简单的方法就是,你在项目的Frameworks下随便找一个,点右键,选show in finder就进去了,然后拷贝进去,Heads文件夹缺省不在那下面,要从\Versions\A下拷过来,可执行文件的GoogleMaps.framework放到文件夹的下一层(好像也在\Versions\A下),然后导入项目的frameworks。然后导入只有23字节的那个GoogleMaps.framework(这个放在项目文件夹下就可以了)。
6、在AppDelegate.h里加入
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navController;
在AppDelegate.m里加入
@implementation BIDAppDelegate
@synthesize window = _window;
@synthesize navController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[GMSServices provideAPIKey:@"mykey"]; //这里填入刚才申请的Key
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
AnimatedCurrentLocationViewController *first = [[AnimatedCurrentLocationViewController alloc] init];
self.navController = [[UINavigationController alloc] initWithRootViewController:first];
[self.window addSubview:navController.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
7、新建不带xib的ViewController,在ViewController.m里加入
@implementation BIDGoolgeViewController
{
GMSMapView *mapView_;
}
- (void)viewDidLoad
{
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:38.913611
longitude:-77.013222
zoom:6];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.myLocationEnabled = YES;
self.view = mapView_;
// Creates a marker in the center of the map.
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(38.913611, -77.013222);
marker.title = @"Sydney";
marker.snippet = @"Australia";
marker.map = mapView_;
}
8、运行,ok了。刚开始只有个图标,其他什么都没有,是因为没有加入Key。
9、omg!忘记了,还有一个GoogleMaps.bundle。在项目里建立一个叫GoogleMaps.framework/Resources的new group,将GoogleMaps.bundle拷贝到项目里,导入到这个new group就可以了。
10、说说下载的另一个文件夹GoogleMapsSDKDemos,看名字就知道是示例代码,我试了很多次,改了n多的设置,即本是调试不通的,(更正一下,1.3.1下面的我全部调通了)那这个东西还有用吗,有!打开项目里的\source\SDKDemos\Samples\,看到好东西没,全是各种ViewController,看你要什么了,自己看英文选择合适的吧!我调试成功了一个AnimatedCurrentLocationViewController,这个会有一个小人跑的动画,但在加载image资源的时候遇到些问题,我后来是这样用的,先看代码用到什么资源,然后在自己的项目中新建一个new group叫Resources,将资源需要的资源倒进来就ok了。
11、移植1.3.1的sdk的示例代码到我新建的项目中,错误解决:
(1)总是报olink链接符号的错误。
原因是sample下的代码没有添加到编译环境当中,在build phases里面加入,或者在项目右键里面添加,但是必须选择正确。(要有个黄色文件夹)
(2)头文件错误
尝试加上前面的文件夹或是不加
(3)无法捕获的异常错误,跳到Main里。
位置在GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
longitude:151.2086
zoom:12];
错误是unrecognized selector sent to class。
解决是在Build setting里面的link里的other link flags加上
-ObjC。
(4)终于解决个大问题,运行到这总报错
self.view= [GMSMapView mapWithFrame:CGRectZero camera:camera];
找了很长时间,最后没有办法再详细看它的错误说明,原来是GoogleMaps.bundle没有加载,现在好了,1 1.3.1的sdk在iOS5.1的环境下在iPad(ios5.1)和iPadmini(ios7.0)下都运行正常。
(5)移植到iOS5.0 非常的纠结,几乎下载的所有的google sdk都会有链接符号的错误,找了一个链接符号少的调 试。报NSURLIsExcludedFromBackupKey Undefined symbols for architecture armv7错,找了一晚上没 解决,今早上找到了,记住这个链 接,很有用http://code.google.com/p/gmaps-api- issues/issues/detail?id=4750,解决办法是在AppDelegate.m里面加上这句:
NSString* const NSURLIsExcludedFromBackupKey = @"NSURLIsExcludedFromBackupKey";
(6)当出现一大堆什么c++啦什么的错误,可能是少了库,我发现我的少了libc++.dylib库。
(7)这个错误前面说过是sdk 1.7.2下面产生的,这里综合一下:
在GMSGeocoder.h文件里
GMSGeocoder error codes, embedded in NSError. */
typedef NS_ENUM(NSInteger, GMSGeocoderErrorCode) {
kGMSGeocoderErrorInvalidCoordinate = 1,
kGMSGeocoderErrorInternal,
};
报错:Expected ';' after top level declarator 一直不能解决。
已经解决了,很开心!
要改成这种写法:(上面的写法意思是告诉你,这种枚举类型里面的值是整型的,枚举还可以是Bool型、 字符型等)
typedef enum {
kGMSGeocoderErrorInvalidCoordinate = 1,
kGMSGeocoderErrorInternal,
}GMSGeocoderErrorCode;