●  在移动互联网时代,移动app能解决用户的很多生活琐事,比如

●  导航:去任意陌生的地方

●  周边:找餐馆、找酒店、找银行、找电影院

●  在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这2  大功 能,必须基于2个框架进行开发

●  Map Kit :用于地图展示

●  Core Location :用于地理定位

●  2个热门专业术语

●  LBS :Location Based Service

●  SoLoMo :Social Local Mobile(索罗门)

CoreLocation框架的使用

● CoreLocation框架使用前提
● 导入框架
● 导入主头文件
#import <CoreLocation/CoreLocation.h>

● CoreLocation框架使用须知
● CoreLocation框架中所有数据类型的前缀都是CL
● CoreLocation中使用CLLocationManager对象来做用户定位

CLLocationManager

● CLLocationManager的常用操作
● 开始用户定位
• - (void)startUpdatingLocation;

● 停止用户定位
• - (void) stopUpdatingLocation;

● 当调用了startUpdatingLocation方法后,就开始不断地定位用户的位
置,中途会频繁地调用代理的下面方法

● - (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations;

• locations参数里面装着CLLocation对象

CLLocation

● CLLocation用来表示某个位置的地理信息,比如经纬度、海拔等等
● @property(readonly,nonatomic)CLLocationCoordinate2Dcoordinate;

• 经纬度
● @property(readonly,nonatomic)CLLocationDistancealtitude;

• 海拔
● @property(readonly,nonatomic)CLLocationDirectioncourse;

• 路线,航向(取值范围是0.0°~359.9°,0.0°代表真北方向)
● @property(readonly,nonatomic)CLLocationSpeedspeed;

• 行走速度(单位是m/s)
● 用- (CLLocationDistance)distanceFromLocation:(const CLLocation*)location

方法可以计算2个位置之间的距离

CLLocationManager

● @property(assign, nonatomic) CLLocationDistance distanceFilter;

● 每隔多少米定位一次
● @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

● 定位精确度(越精确就越耗电)

CLLocationCoordinate2D

● CLLocationCoordinate2D是一个用来表示经纬度的结构体,定义如下
typedef struct {

CLLocationDegrees latitude; // 纬度

CLLocationDegrees longitude; // 经度

}CLLocationCoordinate2D;

● 一般用CLLocationCoordinate2DMake函数来创建CLLocationCoordinate2D

用户隐私的保护

● 从iOS 6开始,苹果在保护用户隐私方面做了很大的加强,以下操作都必须经 过用户批准授权

● 要想获得用户的位置
● 想访问用户的通讯录、日历、相机、相册等等

● 当想访问用户的隐私信息时,系统会自动弹出一个对话框让用户授权

● 开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的 (Privacy - Location Usage Description)

● 一旦用户选择了“Don’t Allow”,意味着你的应用以后就无法使用定位功能
● 为了严谨起见,最好在使用定位功能之前判断当前应用的定位功能是否可用
● CLLocationManager有个类方法可以判断当前应用的定位功能是否可用
• + (BOOL)locationServicesEnabled;

CLGeocoder

● 使用CLGeocoder可以完成“地理编码”和“反地理编码”
● 地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
● 反地理编码:根据给定的经纬度,获得具体的位置信息

● 地理编码方法

● -(void)geocodeAddressString:(NSString*)addressString
completionHandler:
(CLGeocodeCompletionHandler)completionHandler;

● 反地理编码方法

● -(void)reverseGeocodeLocation:(CLLocation*)location
completionHandler:
(CLGeocodeCompletionHandler)completionHandler;

CLGeocodeCompletionHandler

● 当地理\反地理编码完成时,就会调用CLGeocodeCompletionHandler
● typedef void (^CLGeocodeCompletionHandler)(NSArray*placemarks, NSError *error);

● 这个block传递2个参数

• error :当编码出错时(比如编码不出具体的信息)有值

• placemarks :里面装着CLPlacemark对象

CLPlacemark

● CLPlacemark的字面意思是地标,封装详细的地址位置信息
● @property(nonatomic,readonly)CLLocation*location;

• 地理位置

● @property(nonatomic,readonly)CLRegion*region;

• 区域

● @property(nonatomic,readonly)NSDictionary*addressDictionary;

• 详细的地址信息

● @property(nonatomic,readonly)NSString*name;

• 地址名称

● @property(nonatomic,readonly)NSString*locality;

• 城市

实例:Core Location :用于地理定位

#import "HMViewController.h"
#import <CoreLocation/CoreLocation.h> @interface HMViewController () <CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locMgr;
@end @implementation HMViewController - (CLLocationManager *)locMgr
{
if (!_locMgr) {
// 1.创建位置管理器(定位用户的位置)
self.locMgr = [[CLLocationManager alloc] init]; // 2.设置代理
self.locMgr.delegate = self;
}
return _locMgr;
} - (void)viewDidLoad
{
[super viewDidLoad]; if ([CLLocationManager locationServicesEnabled]) {
// 开始定位用户的位置
[self.locMgr startUpdatingLocation]; // [self.locMgr startMonitoringForRegion:<#(CLRegion *)#>]; // self.locMgr.purpose // self.locMgr.distanceFilter = kCLDistanceFilterNone;
// self.locMgr.desiredAccuracy = kcllocationac
} else { // 不能定位用户的位置
// 1.告诉用户检查网络状况
// 2.提醒用户打开定位开关
} [self countDistance];
} - (void)countDistance
{
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude: longitude:];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude: longitude:]; CLLocationDistance distance = [loc1 distanceFromLocation:loc2];
NSLog(@"(%@)和(%@)的距离:%f", loc1, loc2, distance);
} #pragma mark - CLLocationManagerDelegate
/**
* 当定位到用户的位置时,就会调用(调用比较频繁)
*/
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// 数组里面存放的是CLLocation对象, 一个CLLocation就代表一个位置
CLLocation *loc = [locations lastObject]; // 纬度:loc.coordinate.latitude
// 经度:loc.coordinate.longitude
NSLog(@"纬度=%f, 经度=%f", loc.coordinate.latitude, loc.coordinate.longitude); // 停止更新位置(不用定位服务,应当马上停止定位,非常耗电)
[manager stopUpdatingLocation];
} //- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
//{
//
//}
//
//- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
//{
//
//} @end

实例:地理编码 and 反地理编码

#import "HMViewController.h"
#import <CoreLocation/CoreLocation.h> @interface HMViewController ()
@property (nonatomic, strong) CLGeocoder *geocoder; #pragma mark - 地理编码
- (IBAction)geocode;
@property (weak, nonatomic) IBOutlet UITextField *addressField;
@property (weak, nonatomic) IBOutlet UILabel *longitudeLabel;
@property (weak, nonatomic) IBOutlet UILabel *latitudeLabel;
@property (weak, nonatomic) IBOutlet UILabel *detailAddressLabel; #pragma mark - 反地理编码
- (IBAction)reverseGeocode;
@property (weak, nonatomic) IBOutlet UITextField *longtitudeField;
@property (weak, nonatomic) IBOutlet UITextField *latitudeField;
@property (weak, nonatomic) IBOutlet UILabel *reverseDetailAddressLabel;
@end @implementation HMViewController - (CLGeocoder *)geocoder
{
if (!_geocoder) {
self.geocoder = [[CLGeocoder alloc] init];
}
return _geocoder;
} - (void)viewDidLoad
{
[super viewDidLoad]; } /**
* 地理编码:地名 -> 经纬度
*/
- (void)geocode
{
// 1.获得输入的地址
NSString *address = self.addressField.text;
if (address.length == ) return; // 2.开始编码
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
if (error || placemarks.count == ) {
self.detailAddressLabel.text = @"你输入的地址找不到,可能在火星上";
} else { // 编码成功(找到了具体的位置信息)
// 输出查询到的所有地标信息
for (CLPlacemark *placemark in placemarks) {
NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@", placemark.name, placemark.locality, placemark.country, placemark.postalCode);
} // 显示最前面的地标信息
CLPlacemark *firstPlacemark = [placemarks firstObject];
self.detailAddressLabel.text = firstPlacemark.name; CLLocationDegrees latitude = firstPlacemark.location.coordinate.latitude;
CLLocationDegrees longitude = firstPlacemark.location.coordinate.longitude;
self.latitudeLabel.text = [NSString stringWithFormat:@"%.2f", latitude];
self.longitudeLabel.text = [NSString stringWithFormat:@"%.2f", longitude];
}
}];
} /**
* 反地理编码:经纬度 -> 地名
*/
- (void)reverseGeocode
{
NSString *longtitudeText = self.longtitudeField.text;
NSString *latitudeText = self.latitudeField.text;
if (longtitudeText.length == || latitudeText.length == ) return; CLLocationDegrees latitude = [latitudeText doubleValue];
CLLocationDegrees longtitude = [longtitudeText doubleValue]; // 开始反向编码
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longtitude];
[self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
if (error || placemarks.count == ) {
self.reverseDetailAddressLabel.text = @"你输入的经纬度找不到,可能在火星上";
} else { // 编码成功(找到了具体的位置信息)
// 输出查询到的所有地标信息
for (CLPlacemark *placemark in placemarks) {
NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@", placemark.name, placemark.locality, placemark.country, placemark.postalCode);
} // 显示最前面的地标信息
CLPlacemark *firstPlacemark = [placemarks firstObject];
self.reverseDetailAddressLabel.text = firstPlacemark.name; CLLocationDegrees latitude = firstPlacemark.location.coordinate.latitude;
CLLocationDegrees longitude = firstPlacemark.location.coordinate.longitude;
self.latitudeField.text = [NSString stringWithFormat:@"%.2f", latitude];
self.longtitudeField.text = [NSString stringWithFormat:@"%.2f", longitude];
}
}];
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
} @end

最新文章

  1. 主席树——求静态区间第k大
  2. “fatal error C1010”错误解决的三种方法
  3. MVVM开发模式简单实例MVVM Demo
  4. gulp使用技巧-删除node_modules文件夹,解决目录层次太深删除报错的问题
  5. Spring day01笔记
  6. Android之ADB指令
  7. JMeter入门(1):JMeter总体介绍及组件介绍
  8. 从字节理解Unicode(UTF8/UTF16)
  9. Core Audio 在Vista/Win7上实现
  10. 使用Three.js的材质
  11. Rhythmbox音乐播放器常见问题
  12. 浏览器怎么解析一个hmtl文档
  13. FtpHelper ftp操作类库
  14. LeetCode之“字符串”:最长回文子串
  15. 第三次scrum冲刺
  16. 在Visualforce页面中使用Visual Flow
  17. SqlDataAdapter更新数据
  18. RHEL6/7 x86_64下cachefilesd占用cpu达到100%
  19. Reshaper cannot resolve symbol
  20. cmake3.8X64编译opencv3.2出现opencv_ffmpeg、opencv_ffmpeg_64、ippicv_windows_20151201.zip无法下载问题解决方案

热门文章

  1. Robot Framework变量的使用技巧
  2. PIE SDK K-Means分类
  3. Centos安装zeromq, jzmq
  4. GreenPlum 大数据平台--运维(二)
  5. unity的技术博客
  6. WPF 父子窗体联动
  7. e.target和e.event和event.srcElement
  8. 从数组去重这个函数来体验es6的高效率
  9. 3、card 卡片
  10. JS &amp;&amp; || 陷阱 javascript 逻辑与、逻辑或 【转】