- 浏览: 644303 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
lizaochengwen:
网络请求碰到的中文乱码使用encodeURL吧- (NSStr ...
iPhone开发/iPad开发 中文乱码问题 -
hhb19900618:
还是没弄懂怎么解决了中文乱码? 正确代码能重写贴出吗
iPhone开发/iPad开发 中文乱码问题 -
zhengjj_2009:
我的理解是讲ipa文件解压缩之后再重新打包,已经破坏了签名,所 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
zhengjj_2009:
我参考你的“ 从ipa格式的母包生成其它渠道包的shell脚本 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
同一片天空:
问题果然解决了
iOS 搭建 XMPP实现环境
个人觉得地理位置这部分的知识其实是相当有趣的。说到定位其实在大多数的社交软件中都有这样的一个功能,用户可以共享自己的位置并且查看其他用户的位置,从而更容易地结交一些附近或者在同一地区的朋友,又或者在地图上显示自己的当前位置,并且显示附近的餐厅或者咖啡厅。这些功能看起来是挺复杂,但在实际的开发过程中,iOS为我们封装了大部分的功能,让我们不需要学习太底层的知识,通过他提供的两个库就能轻松实现。接下来我会一步一步地讲述相关知识。
1、获取当前定位
iOS提供了一个叫作CoreLocation.framework的框架。使用他可以取到自己的定位信息(经纬度)。请参考下面代码片段:
if([CLLocationManager locationServicesEnabled]){ //定位功能开启的情况下进行定位 CLLocationManager *manager = [[CLLocationManager alloc] init]; manager.distanceFilter = kCLDistanceFilterNone; manager.desiredAccuracy = kCLLocationAccuracyBest; manager.delegate = self; [manager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { [manager stopUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { [manager stopUpdatingLocation]; }
如上面代码所示CLLocationManager就是用于获取定位信息对象类,在实际应用中可以根据自己的需要来设置定位的更新频率以及定位准确度。其中代码中的distanceFilter表示更新位置的距离,假如超过设定值则进行定位更新,否则不更新。代码中的kCLDistanceFilterNone表示不设置距离过滤,即随时更新地理位置。desiredAccuracy属性表示取得定位的精度,kCLLocationAccuracyBest表示最精确,但也预示着需要消耗更多的时间和电量,所以应该根据需要设定。
那么CLLocationManager是通过什么方法来开启定位的呢?他是通过调用startUpdatingLocation开启定位功能,然后使用stopUpdatingLocation停止定位,其中定位信息是通过loctionManager:didUpdateToLocation:fromLocation;委托方法来通知委托对象的,因此委托对象必须实现CLLocationManagerDelegate委托。在返回定位信息委托方法中主要的两个参数是newLocation和oldLocation,newLocation表示最新定位,oldLocation表示上一次的定位信息。这两个都是CLLocation对象。以下是CLLocation的属性说明:
属性 描述 altitude 海拔高度 coordinate 经纬度 course 行驶方向 horizontalAccuracy 水平方向的精确度 Speed 行驶速度 timestamp 时间戳 verticalAccuracy 垂直方向的精确度
2、获取地理位置信息
当你取到了一个经纬度信息时,也许还有这样的一个需求,那就是当前的经纬度所对应的地理位置信息是什么。那么这时候我们需要用到框架来为我们实现这一功能,那就是MapKit.framework。在这个框架中有一个叫MKReverseGeocoder的类可以帮助我们实现反向解析地理位置。请看一下代码:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; geocoder.delegate = self; [geocoder start]; } - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark { NSLog(@"\n country:%@\n postalCode:%@\n ISOcountryCode:%@\n locality:%@\n subLocality:%@\n administrativeArea:%@\n subAdministrativeArea:%@\n thoroughfare:%@\n subThoroughfare:%@\n", placemark.country, placemark.postalCode, placemark.ISOcountryCode, placemark.administrativeArea, placemark.subAdministrativeArea, placemark.locality, placemark.subLocality, placemark.thoroughfare, placemark.subThoroughfare); } - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error { NSLog(@"reverse geocoder fail!!"); }
上面的代码是在获取到经纬度后,立刻进行反向地理位置解析的。其实MKReverseGeocoder用法也比较简单,通过经纬度初始化后直接调用start方法就可以实现反向解析了,然后等待返回,其返回是通过委托形式通知的。所以委托对象必须实现MKReverseGeocoderDelegate委托。解析成功后会返回一个MKPlacemark的对象里面包含了相关的地理位置信息(包括国家、地区、街道等)。
但从iOS5之后MKReverseGeocoder成为了不推荐使用的类。因此有一个新的类取代了他的作用,那就是CLGeocoder类,使用该类进行反向解析也非常容易,请看下面代码:
CLGeocoder *geocoder=[[CLGeocoder alloc] init]; [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) { CLPlacemark *placemark=[placemarks objectAtIndex:0]; NSLog(@"name:%@\n country:%@\n postalCode:%@\n ISOcountryCode:%@\n ocean:%@\n inlandWater:%@\n locality:%@\n subLocality:%@ \n administrativeArea:%@\n subAdministrativeArea:%@\n thoroughfare:%@\n subThoroughfare:%@\n", placemark.name, placemark.country, placemark.postalCode, placemark.ISOcountryCode, placemark.ocean, placemark.inlandWater, placemark.administrativeArea, placemark.subAdministrativeArea, placemark.locality, placemark.subLocality, placemark.thoroughfare, placemark.subThoroughfare); }];
从代码来看,CLGeocoder类没有使用委托的形式通知返回状态,而是通过block的方式进行回调,而且MKReverseGeocoder委托只返回了一个地标位置,但是CLGeocoder则返回了一个包含多个地标位置的数组,但这个数组在通常状态下是只有一个元素,如果存在多个元素那证明了给定解析的经纬度被解析到多个不同的地标信息。如果解析错误或者调用cancel方法则此参数为nil。
3、地图显示
想更加形象地表现出位置信息靠文字的描述是远远不够的,因为使用地图来显示地理位置将会给用户带来全新的体验。在iOS里面已经将Google地图封装到SDK里面了,我们可以用很少的代码来实现很多在地图上的操作(如标记位置、绘画线路等)。下面的代码是生成一张地图并显示到界面上:
- (void)viewDidLoad { [super viewDidLoad]; MKMapView *mapView=[[MKMapView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 460.0)]; mapView.delegate = self; [self.view addSubview:mapView]; [mapView release]; }
这够简单吧,上面的设置地图委托对象是因为在下面要标记地理位置时需要用到的。那么如何把取到的经纬度信息显示到地图上呢?其实每个坐标信息在地图中显示后都对应一个MKAnnotationView,而MKAnnotationView又负责解析了一个实现MKAnnotation协议的数据对象。因此我们首先要做的事情就是把取到的经纬度转换为MKAnnotation协议对象。先定义一个实现MKAnnotation协议的类:
@interface DemoAnnotation : NSObject<MKAnnotation> { CLLocationCoordinate2D _coordinate; } -(id)initWithCoordinate:(CLLocationCoordinate2D)coordinate; @end @implementation DemoAnnotation @synthesize coordinate=_coordinate; -(id)initWithCoordinate:(CLLocationCoordinate2D)coordinate{ if (self = [super init]) { _coordinate=coordinate; } return self; } -(void)setCoordinate:(CLLocationCoordinate2D)newCoordinate{ _coordinate=newCoordinate; } -(NSString *)title{ return @”我的位置”; } -(NSString *)subtitle{ return nil; } @end
上面的类只是简单地保存了经纬度信息。记得注意的是MKAnnotation协议中的title和subtitle的作用,如果你在显示AnnotationView设置其canShowCallout属性为YES时,则当用户点击AnnotationView时会弹出一个Callout视图,用于显示title和subtitle,假如设置title为nil那么即使canShowCallout为YES也不会弹出Callout视图。
接下来要改写一下获取定位成功后的方法,等待获取定位成功后把经纬度设置到地图上显示。实现代码如下:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { DemoAnnotation *annotation = [[DemoAnnotation alloc] initWithCoordinate:newLocation.coordinate]; [_mapView addAnnotation:annotation]; [annotation release]; MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; geocoder.delegate = self; [geocoder start]; }
上述代码中加粗部分的代码就是把经纬度信息封装到刚才定义好的对象中。然后通过addAnnotation方法传递给MapView;这里的_mapView是把之前viewDidLoad方法中的临时变量改变为类属性以达到跨方法引用的目的。经过上面步骤已经把我的位置引入到地图里面了,但现在还不会显示在地图上,因为还需要实现MapView中的协议,告诉MapView如何显示你Annotation。以下代码采用iOS中默认的大头针样式来显示位置。如下:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { NSString *annotationViewId=@"CurrentUserAnnotationView"; MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:annotationViewId]; if (annotationView==nil) { annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewId] autorelease]; annotationView.canShowCallout = YES; } return annotationView; }
上面的协议方法就是MapView告诉你他需要显示哪个annotation,然后显示的样式由用户你自己决定,但必须要继承MKAnnotationView类。
到这里对于定位和地图的应用就告一段落了,当然关于 MKMapView 还有一些更加高级的特性,例如:动态编辑 Annotation 、绘画路线图等应用我在这里暂时不说了,等偶再研究透彻一点再给大家分享。
发表评论
-
SOCK_STREAM和SOCK_DGRAM
2015-07-23 20:08 1571sock_stream 是有保障的(即能保证数据正确传送到 ... -
SOCKET bind INADDR_LOOPBACK和INADDR_ANY的区别
2015-07-23 19:49 2008今天写程序时候,服务器端启动了,然后客户端总是连接不上,con ... -
htons()
2015-07-23 19:26 534在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺 ... -
使用symbolicatecrash分析crash文件
2015-03-10 11:32 1124原文 http://www.cnblogs.com/ning ... -
程序设计中的计算复用(Computational Reuse)
2015-02-10 10:18 611从斐波那契数列说起 ... -
didReceiveMemoryWarning
2015-02-09 16:11 489IPhone下每个app可用的内存是被限制的,如果一个app使 ... -
iOS开发中怎么响应内存警告
2015-02-09 16:08 608好的应用应该在系统内存警告情况下释放一些可以重新创建的资源。在 ... -
ASIHTTPRequest多次重复请求的问题
2014-12-17 14:34 592在一个车票订购的项目中,点击一次订购,却生成了2次订单,通过抓 ... -
从 CloudKit 看 BaaS 服务的趋势
2014-09-26 11:51 693从 6 月份 WWDC 苹果发布 ... -
ios编程--AVCapture编程理解
2014-09-26 11:03 8750、媒体采集的几个东西。这里所需要明白的是,在这个流程中,这里 ... -
NSURLProtocol
2014-09-25 10:42 7621、http://nshipster.com/nsurlpro ... -
关于iOS8的extension插件
2014-09-25 10:41 1220关于iOS8的extension插件,有兴趣的同学可以参考一下 ... -
【转】ios app在itunesConnect里面的几种状态
2014-08-05 10:34 1094Waiting for Upload (Yellow) Ap ... -
[转]iOS Dev (45) iOS图标与切片处理工具Prepo
2014-02-07 17:02 991iOS Dev (45) iOS图标与切片处理工具Prepo ... -
phoneGap开发IOS,JS调用IOS方法/phoneGap插件开发
2014-01-13 17:49 1210前沿 废话不说phoneGap是什么不多介绍,官方网站: h ... -
如何在IOS平台下搭建PhoneGap开发环境(PhoneGap2.5)
2014-01-13 15:23 703由于在下最近在做基于HTML5的跨平台移植,搭建环境的时候着实 ... -
xcode 4 制作静态库详解
2013-12-20 18:27 487最近在做Apple的IOS开发,有开发静态库的需求,本身IOS ... -
【翻译】ios教程-创建静态库
2013-12-20 18:19 3016作者:shede333 主页:htt ... -
封装自己的控件库:iPhone静态库的应用
2013-12-20 17:03 516由于iPhone 控件的极度匮乏和自定义组件在重用上的限制,在 ... -
iphone:使用NSFileManager取得目录下所有文件(遍历所有文件)
2013-11-18 17:56 826From:http://note.sdo.com/u/xiao ...
相关推荐
编辑推荐《iPhone与iPad开发实战:iOS经典应用剖析》是一本关于iOS项目分析与实战的教程,旨在帮助读者能够实际动手开发一些iOS项目,同时能够学习到一些理论知识。《iPhone与iPad开发实战:iOS经典应用剖析》适合作为...
iPhone与iPad开发实战:iOS经典应用剖析pdf(附源码)
iPhone开发实战 iPhone开发 iPhone iPhone4 iPhone开发实战 iPhone开发 iPhone iPhone4
iPhone开发实战
iPhone开发秘籍:第2版(The iPhone Developer's Cookbook),英文版,清晰PDF版。iphone开发必备佳作,在第一版的基础上进行了全面修订和大量扩充。iPhone开发的重量级参考书,揭示官方文档未详述的细节,代码示例...
iPhone 开发实战 pdf + 书籍源码 (全) 绝对完全的pdf 和源代码
搜集到的,感觉不错,与大家分享。 本书是一本关于iOS项目分析与实战的教程,旨在帮助读者能够实际动手开发一些iOS项目,同时能够学习到一些理论知识。
本书全面探讨了iPhone平台的两种编程方式——Web开发和SDK编程。全在Web开发方面,分别介绍了三个iPhone Web库,即WebKit、iUI和Canvas,并讨论了Web开发环境Dashcode,最后阐述Web应用程序的调试。在SDK开发方面,...
目前市面上不乏iPhone App开发的书籍,但要做出成功的产品,需要的绝不仅仅是开发优秀的软件。本书将向你展示完整的开发过程,从下载工具,开发应用,进行测试,通过苹果的审核,到推销和维护你的产品。本书适合...
从monotouch和.net开发环境到objective-c和c#开发语言,从基于monotouch进行iphone开发的编程方法到应用程序的发布和销售等,《iPhone高级编程:使用Mono Touch和.NET/C#》涵盖了基于monotouch进行iphone应用程序...
新手iPhone开发 ,让您学的轻松,看得放心.
苹果iphone开发系列:Objective-C初學者指南 该种语言的最大特色是中括号【】
ios学习资料 iPhone+App开发实战手册,又相关基础可以看看写的很全
一本很好的iphone实战开发书籍,主要用于介绍ios平台的开发,适用于ipad iphone开发
《iPhone开发实战》一书结合示例对iPhone主要两种编程方式——Web开发和SDK编程的基本流程、基本原理和基本原则给出了详细而通俗的讲解。 上部主要讲WEB开发,下部主要讲SDK开发
这是一本很好的iphone开发实战书籍,主要用于介绍如何进行ios开发,也适用于ipad
其中包括了iphone开发实战的所有源代码,希望对你有所帮助。