Location是为处理用户位置信息若计划之一个framework必须根据两独框架进行开。

当当下等同段节吃,你以见面模仿到于公的app中安使iPhone中之GPS。你将见面学会怎么获得用户之职务,同时在地图上标有位置。本章内容涵盖了
地图套件(Map
Kit)和苹果店供的地图、方向框架。通过上本章节的始末,你立即就足以搞定基于位置一定的以。

每当iOS开发被,要惦记加入地图的位置就有限不胜职能,必须冲两个框架进行支付:Map
Kit(用于地图显示)、Core Location(用于地理定位)

提供用户的岗位信息是开iOS应用最冲动的特点,在地形图及显得用户的号需要少只步骤。

地图定位

先是步用Core Location来搜集用户之位置。Core
Location是一致名目繁多类的集结,通过配备的GPS和蜂窝获取位置信息,还能够借助WIFI获取用户信息。Core
Location
是出于苹果公司供的广大frameworks中之一个。Frameworks是均等组类的集合,为切实的有任务而规划的同样模拟工具。我们本为此Core
Location举一个例子,Core
Location是为处理用户位置信息若设计的一个framework。Core
Data是为处理多少要规划的一个framework。这些framework是可选的,因此需要先将这些框架导入到工程中后,才会采取这些框架。

CoreLocation框架的使用

  • 导入框架(iOS5下不再需要)
![](https://upload-images.jianshu.io/upload_images/1803320-a14a5c8cb8928995.png)

导入CoreLocation框架
  • 导入头文件:#import<CoreLocation/CoreLocation.h>
  • CoreLocation框架下须知
    • CoreLocation框架中有着数据类型的前缀都是CL
    • CoreLocation中利用CLLocationManager对象来举行用户定位

第二步是以地形图中标注出用户之职位。苹果公司供了Map
Kit框架,帮助我们绘制和治本地图。在Xcode
6中导入框架非常容易。首先Project
Navigator中点击项目名称,点击名为Capabilities的tab选项按钮,向下滚动找到Maps。将地图的上马要处On的状态,这时MapKit框架已经补充加至工程中了。现在虽会以工程中找到MapKit,但是导入流程还不曾形成。MapKit还亟需导入controller
file中。我们下列一行代码完成导入工作:

CLLocationManager

类方法 说明
+ (BOOL)locationServicesEnabled; 检测整个iOS系统的位置服务是否开启,即iPhone手机上的定位设置。通常如果用户没有启用定位服务可以提示用户打开定位服务
+ (CLAuthorizationStatus)authorizationStatus; 指当前应用的定位服务授权状态,返回枚举类型:kCLAuthorizationStatusNotDetermined: 用户尚未做出决定是否启用定位服务kCLAuthorizationStatusRestricted: 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权kCLAuthorizationStatusDenied :用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态kCLAuthorizationStatusAuthorizedAlways: 应用获得授权可以一直使用定位服务,即使应用不在使用状态kCLAuthorizationStatusAuthorizedWhenInUse: 使用此应用过程中允许访问定位服务
属性 说明
desiredAccuracy 定位精度(越精确越耗电),枚举类型:kCLLocationAccuracyBest:最精确定位CLLocationAccuracy kCLLocationAccuracyNearestTenMeters:十米误差范围kCLLocationAccuracyHundredMeters:百米误差范围kCLLocationAccuracyKilometer:千米误差范围kCLLocationAccuracyThreeKilometers:三千米误差范围
distanceFilter 位置信息更新最小距离,只有移动大于这个距离才更新位置信息,默认为kCLDistanceFilterNone:不进行距离限制
对象方法 说明
startUpdatingLocation 开始定位追踪,开始定位后将按照用户设置的更新频率b不断地定位用户的位置,频繁地执行**-(void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray )locations方法来反馈定位信息,参数locations是一个数组,里面的元素对象是CLLocation对象
stopUpdatingLocation 停止定位追踪
startUpdatingHeading 开始导航方向追踪
stopUpdatingHeading 停止导航方向追踪
startMonitoringForRegion: 开始对某个区域进行定位追踪。如果用户进入或者走出某个区域会调用– (void)locationManager:(CLLocationManager )manager didEnterRegion:(CLRegion )region– (void)locationManager:(CLLocationManager )manager didExitRegion:(CLRegion )region代理方法反馈相关信息
stopMonitoringForRegion: 停止对某个区域进行定位追踪
requestWhenInUseAuthorization 请求获得应用使用时的定位服务授权,注意使用此方法前在要在info.plist中配置NSLocationWhenInUseUsageDescription
requestAlwaysAuthorization 请求获得应用一直使用定位服务授权,注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription
代理方法 说明
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; 位置发生改变后执行(第一次定位到某个位置之后也会执行)
– (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading; 导航方向发生变化后执行
– (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 进入某个区域之后执行
– (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 走出某个区域之后执行

#import "ForthViewController.h"

#import <CoreLocation/CoreLocation.h>

@interface ForthViewController ()<CLLocationManagerDelegate>

// 声明位置管理器属性
@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation ForthViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.locationManager = [CLLocationManager new];

    // [CLLocationManager locationServicesEnabled]这句话检测的是整个iOS系统的位置服务是否开启,即iPhone手机上的定位设置。通常如果用户没有启用定位服务可以提示用户打开定位服务
    if (![CLLocationManager locationServicesEnabled])
    {
        NSLog(@"手机定位服务当前可能尚未打开,请设置打开");
        return;
    }
    /*
    [CLLocationManager authorizationStatus]指的是当前应用的定位服务授权状态,返回枚举类型
     kCLAuthorizationStatusNotDetermined:用户尚未做出决定是否启用定位服务
     kCLAuthorizationStatusRestricted:没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
     kCLAuthorizationStatusDenied:用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
     kCLAuthorizationStatusAuthorizedAlways:应用获得授权可以一直使用定位服务,即使应用不在使用状态
     kCLAuthorizationStatusAuthorizedWhenInUse:使用此应用过程中允许访问定位服务
    */
    // 如果没有授权则请求用户授权
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)
    {
        NSLog(@"请求用户授权");
        [self.locationManager requestWhenInUseAuthorization];
    }
    // 如果被授权
    else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse)
    {
        // 设置代理
        self.locationManager.delegate = self;
        /*
         kCLLocationAccuracyBest:最精确的,也是最耗电的,越精确越耗电
         kCLLocationAccuracyNearestTenMeters:十米误差范围
         kCLLocationAccuracyHundredMeters:百米误差范围
         kCLLocationAccuracyKilometer:千米误差范围
         kCLLocationAccuracyThreeKilometers:三千米
        */
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        // 定位频率(每隔多少米定位一次,单位是米)
//        CLLocationDistance distance = 10.0;// 每隔十米定位一次
//        self.locationManager.distanceFilter = distance;
        // 定位频率设置为kCLDistanceFilterNone的话,会不停地定位,只有几秒的延时
        self.locationManager.distanceFilter = kCLDistanceFilterNone;
        // 开始定位
        [self.locationManager startUpdatingLocation];
    }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // 取出位置
    CLLocation *location = [locations firstObject];
    // 位置坐标
    CLLocationCoordinate2D coordinate = location.coordinate;
    NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


// 让模拟器演示定位
#ifdef TARGET_IPHONE_SIMULATOR
@interface CLLocationManager (Simulator)

-(void)startUpdatingLocation;

@end

@implementation CLLocationManager (Simulator)

-(void)startUpdatingLocation
{
    float latitude = 32.061;
    float longitude = 118.79125;
    CLLocation *setLocation= [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
    NSArray *array = [NSArray arrayWithObject:setLocation];
    [self.delegate locationManager:self didUpdateLocations:array];}
@end
#endif // TARGET_IPHONE_SIMULATOR
import MapKit

地理编码和反编码

运CLGeocoder可以成功地理编码和倒地理编码

  • 地理编码:根据加的地名,获得实际的职务信息(比如经纬度、地址之完备等)
  • 反倒地理编码:根据加的中纬度,获得具体的职务信息

地理编码方法:- (void)geocodeAddressString:(NSString *)addressString
completionHandler:(CLGeocodeCompletionHandler)completionHandler;
反地理编码方法:- (void)reverseGeocodeLocation:(CLLocation *)location
completionHandler:(CLGeocodeCompletionHandler)completionHandler;

//  地理编码、反地理编码

// 地理编码:根据给定的位置(通常是地名),确定地理坐标(经纬度)
// 反地理编码:根据给定地理坐标(经纬度),确定位置信息(街道、门牌等等)
#import "SecondViewController.h"

// 引入定位头文件
#import <CoreLocation/CoreLocation.h>

@interface SecondViewController ()

// 声明编码属性
@property (nonatomic, strong) CLGeocoder *geocoder;

@end

@implementation SecondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化编码对象
    self.geocoder = [CLGeocoder new];
//    [self getCoordinateByAddress:@"北京市海淀区清河"];
    [self getAddressByLatitude:40.0305627852 longitude:116.3435577061];
}
#pragma mark ------------------ 地理编码 --------------------
- (void)getCoordinateByAddress:(NSString *)address
{
    [self.geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
     {
         // 获取第一个地标,地标中存储了详细的地址信息。注意:一个地名可能搜索出多个地址
         CLPlacemark *placeMark = [placemarks firstObject];
         // 获取位置
         CLLocation *location = placeMark.location;
         // 获取区域
         CLRegion *region = placeMark.region;
         // 详细信息
         NSDictionary *dic = placeMark.addressDictionary;
         // 地名
         NSString *name = [NSString stringWithString:[placeMark.name stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
         // 街道
          NSString *thoroughFare = placeMark.thoroughfare;
         // 街道相关信息
         NSString *subThoroughfare = placeMark.subThoroughfare;
          // 城市
          NSString *locality = placeMark.locality;
          // 州
          NSString *administrativeArea = placeMark.administrativeArea;
          // 其他行政区域信息
          NSString *subAdministrativeArea = placeMark.subAdministrativeArea;
          // 邮编
          NSString *postalCode = placeMark.postalCode;
          // 国家编码
          NSString *ISOcountryCode = placeMark.ISOcountryCode;
          // 国家
          NSString *country = placeMark.country;
          // 水源、湖泊
          NSString *inlandWater = placeMark.inlandWater;
          // 海洋
          NSString *ocean = placeMark.ocean;
          // 关联或者利益相关的地标
          NSArray *areasOfInterest = placeMark.areasOfInterest;
         NSLog(@"\n位置:%@\n区域:%@\n详细信息:%@\n名字:%@\n街道:%@\n街道相关信息:%@\n城市:%@\n州:%@\n其他行政区域信息:%@\n邮编:%@\n国家编码:%@\n国家:%@\n水源、湖泊:%@\n海洋:%@\n关联或者利益相关的地标:%@\n", location, region, dic, name, thoroughFare, subThoroughfare, locality, administrativeArea, subAdministrativeArea, postalCode, ISOcountryCode, country, inlandWater, ocean, areasOfInterest);
     }];
}
#pragma mark ----------------- 反地理编码 -----------------
- (void) getAddressByLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude
{
    // 初始化位置信息
    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
    // 反地理编码
    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
     {
         CLPlacemark *placeMark = [placemarks firstObject];
         NSLog(@"详细信息:%@", placeMark.addressDictionary);
         NSLog(@"地名:%@", [NSString stringWithString:[placeMark.addressDictionary[@"Name"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]);
     }];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

地理编码和反地理编码方法中呢得调用系统自带的地图定位(需要出示地图的语,首先得导入MapKit框架,即引入头文件#import
<MapKit/MapKit.h>)

//  通过地理编码调用系统地图定位

#import "ThirdViewController.h"

#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface ThirdViewController ()

@property (nonatomic, strong) CLGeocoder *geocoder;

@end

@implementation ThirdViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.geocoder = [CLGeocoder new];

//    [self location_1];
    [self location_2];
}
#pragma mark ------------- 确定一个城市的位置 --------------
- (void)location_1
{
    [self.geocoder geocodeAddressString:@"北京市" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
    {
        // 获取第一个地标
        CLPlacemark *clplaceMark = [placemarks firstObject];
        // 将定位地标转换为地图地标
        MKPlacemark *mkplaceMark = [[MKPlacemark alloc] initWithPlacemark:clplaceMark];
        // 字典中放一个地图类型
        NSDictionary *options = @{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard)};
        // 初始化地图组
        MKMapItem *maoItem = [[MKMapItem alloc] initWithPlacemark:mkplaceMark];
        // 打开地图,根据地图类型
        [maoItem openInMapsWithLaunchOptions:options];
    }];
}
#pragma mark -------------- 确定两个城市的位置 -------------
- (void)location_2
{
    [self.geocoder geocodeAddressString:@"北京市" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
     {
         // 获取第一个地标
         CLPlacemark *CLplaceMarkBJ = [placemarks firstObject];
         // 将定位地标转换为地图地标
         MKPlacemark *MKplaceMarkBJ = [[MKPlacemark alloc] initWithPlacemark:CLplaceMarkBJ];

         // 注意:地理编码一个只能定位一个城市,不能同时定位,想要再次定位需要将第二个地理编码方法放到第一个地理编码方法的回调函数中进行第二个城市的定位
         [self.geocoder geocodeAddressString:@"石家庄" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
          {
              // 获取第一个地标
              CLPlacemark *CLplaceMarkSJZ = [placemarks firstObject];
              // 将定位地标转换为地图地标
              MKPlacemark *MKplaceMarkSJZ = [[MKPlacemark alloc] initWithPlacemark:CLplaceMarkSJZ];
              // 字典中放一个地图类型
              NSDictionary *Options = @{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard)};
              MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:MKplaceMarkBJ];
              MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:MKplaceMarkSJZ];

              [MKMapItem openMapsWithItems:@[item1, item2] launchOptions:Options];
          }];
     }];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

然,MapKit类和协议就导入到controller文件中了。MapKit中的切近及商量都是以MK开头的。

地图显示

Page 213

MapKit框架的使

  • 导入框架(iOS5之后不再需要程序员导入)

导入MapKit框架

  • 导入头文件 #import <MapKit/MapKit.h>
  • MapKit框架下须知
  • MapKit框架中拥有数据类型的前缀都是MK
  • MapKit有一个于关键之UI控件:MKMapView,专门用于地图显示,下表总结了部分MKMapView常用的性能与方式
属性 说明
zoomEnabled 触摸缩放(默认可缩放)
scrollEnabled 移动(默认可移动)
mapType 地图类型,是一个枚举:MKMapTypeStandard :标准地图,一般情况下使用此地图即可满足;MKMapTypeSatellite :卫星地图;MKMapTypeHybrid :混合地图,加载最慢比较消耗资源;
userTrackingMode 跟踪类型,是一个枚举:MKUserTrackingModeNone :不进行用户位置跟踪;MKUserTrackingModeFollow :跟踪用户位置;MKUserTrackingModeFollowWithHeading :跟踪用户位置并且跟踪用户前进方向;
userLocation 用户位置,只读属性
annotations 当前地图中的所有大头针,只读属性
对象方法 说明
– (void)addAnnotation:(id <MKAnnotation>)annotation; 添加大头针,对应的有添加大头针数组
– (void)removeAnnotation:(id <MKAnnotation>)annotation; 删除大头针,对应的有删除大头针数组
– (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated; 设置地图显示区域,用于控制当前屏幕显示地图范围
– (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated; 设置地图中心点位置
– (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view; 将地理坐标(经纬度)转化为数学坐标(UIKit坐标)
– (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view; 将数学坐标转换为地理坐标
– (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier; 从缓存池中取出大头针,类似于UITableView中取出UITableViewCell,为了进行性能优化而设计
– (void)selectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated; 选中指定的大头针
– (void)deselectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated; 取消选中指定的大头针
代理方法 说明
– (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 用户位置发生改变时触发(第一次定位到用户位置也会触发该方法)
– (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 显示区域发生改变后触发
– (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView; 地图加载完成后触发
– (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation; 显示大头针时触发,返回大头针视图,通常自定义大头针可以通过此方法进行
– (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view; 点击选中某个大头针时触发
– (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view; 取消选中大头针时触发
– (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay; 渲染地图覆盖物时触发

Core Location

赶巧而之前所说之,Core Location是同样密密麻麻查找用户位置的近乎的成团。Core
Location中出三只检测用户位置的主意。第一独章程是Significant-Change
Location。这个办法能够节约电池电量,它仅仅于用户之职明显改观时才会更新位置。第二单方法是Location
Services,可以自主确定稳定更新的规则。最后一种方式是Regional
Monitoring方法,使用附近的地理区域边界或Bluetooth
beacons来稳定。本书要介绍第二栽方式:Location
Services,它是最常用到的主意。

又多信息要参见苹果商店之Location and Maps Programming
Guide。

收获用户位置要以Core Location框架,当您拿Maps
capabilities开关切换成On(开)状态时,Xcode并无机关导入Core
Location框架,需要我们手动导入,请圈之下四单步骤:

  1. 点击Project Navigator上之蓝色工程图标;
  2. Editor显示工程的详细信息,滑倒最下方;
  3. 在Link Binary with Libraries下方点击Add;
  4. 摘Core Location,然后点击Add。

Core Location框架就会补加至Project
Navigator中,我们还索要在controller中形容一行代码才能够收获这框架:

import CoreLocation

手机用户的位置好耗电量,它于其余的职责需要重多的电池电量和天线频率,所以管您的App只有在用位置时才获位置,一旦得到岗位,就把这个力量关闭,如果明天尚待地理位置,可以利用期更新功能

每当博用户位置之前,很重要的等同码事是先期检查一定服务是否可用。定位服务无法用或是出于以下几栽情形:

  • 用户以设置中关闭了Location Services(定位服务)。
  • 用户禁止你的App使用Location Services(定位服务)。
  • 装备处飞行模式或连续不了网。

Page 214 | Chapter 8 : Maps and Location

Core
Location提供了号称吧locationServicesEnabled的办法来检查装置的固定服务是否可用,locationServicesEnabled办法通过布尔列返回值来确定定位服务是否可用,true可用,false不可用。

Requesting User Location

通过CLLocationManager类来请求用户位置。首字母CL代表Core Location。The
location
manager用于收集参数与被定位服务。创建CLLocationManager对象以及创其他的对象类似。举例说明:

var locationManager: CLLocationManager = CLLocationManager()

CLLocationManager有有特性是要要装的。

desiredAccuracy属性是枚举类型,枚举,就是用一个重点词代表一个数字。枚举有点像是基本上选题,你不能不从选中选取有一个值来。desiredAccuracy属性有脚有价值:

kCLLocationAccuracyBest
顶精准的永恒,也是极致消耗电量的选取
kCLLocationAccuracyNearestTenMeters
精准度在十米范围外
kCLLocationAccuracyHundredMeters
准确度在一百米克外
kCLLocationAccuracyKilometer
精确度在一千米限外
kCLLocationAccuracyThreeKilometers
精确度在三千米范围外

精准度越强,电量消耗越怪。我们如果挑选能够满足低要求的精准度级别。如果是像Google地图之类的App来追踪用户的岗位,那么kCLLocationAccuracyNearestTenMeters或者kCLLocationAccuracyHundredMeters就可以满足我们的需求。如果App只需要提供用户所在城市,像是Twitter中的定位,kCLLocationAccuracyKilometer或者kCLLocationAccuracyThreeKilometers即便足以满足我们的需求。大多数情形下,一般不欲kCLLocationAccuracyBest

装desiredAccuracy属性的道和安装任何对象的性一样:

locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters

Core Location | Page 215

CLLocationManager也得delegate属性。CLLocationManage
delegate遵循CLLocationManagerDelegate协议。无论何时起了岗位更新或者出现谬误,delegate都见面收下到警示。为了接收这些警告,delegate必须经CLLocationManagerDelegate协议以及警报保持联系。controller必须声明遵循协议,将CLLocationManagerDelegate添加到类的顶部:

class ViewController: UIViewController, CLLocationManagerDelegate

怀念使接定位警高,要以locationManager(_:,didUpdateLocations:)办法。每当定位信息变更之常常,这个法子就是会见让调用:

func locationManger(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!) {
    println("Location found")
}

想念如果在外时候都能接Core
Location的左警告,需要以locationManager(_: didFailWithError:)方法:

func locationManager(manager: CLLocationManager!, didFailWithError error:NSError!) {
    println("Error!")
}

苟以协议并下中的法门后,就非得要安装delegate的习性:

locationManager.delegate = self

于激活定位服务前,
用户必须允许app使用用户之岗位信息。定位服务来一定量种植特许项目。第一种是requestWhenInUseAuthorization;授权App仅限前台运行的时采用位置信息。
第二种是requestAlwaysAuthorization.
授权App在前台要后台运行都得收获用户的职信息,第二个授权都见面吃app提供追踪用户位置的力量。调用授权的措施是:

locationManager.requestWhenInUseAuthorization()

locationManager.requestAlwaysAuthorization()

赢得授权后,调用startUpdatingLocation()办法被定位服务:

locationManager.startUpdatingLocation()

这样,locationManager会根据有关要求开追踪并回用户位置信息。

Page 216 | Chapter 8 : Maps and Location

locationManager (_:, didUpdateLocations:)方法会提供CLLocation数组,按照出现前后顺序排列。数组中足足会发生一个对象。数组中的各国一个靶都是是一个CLLocation。CLLocation这个类似为具体的岗位整理组织CLLocationManager的职务数据。CLLocation跟踪地理坐标,海拔,速度,方向,甚至席卷定位准确度。CLLocation拥有广大卓有成效的性质:

coordinate
CLLocationCoordinate2D, 纬度坐标和经度坐标
altitude
海拔高度,单位:米
timestamp
赢得到数量常常的年华及日期
description
从而字符串的格式返回CLLocation,可以就此print()打印出

告记住,一旦您沾了公待之音,必须停止定位服务功能。为了停息这些劳务,在CLLocationManager中调用stopUpdatingLocation()
:

manager.stopUpdatingLocation()

推个例,在locationManager( manager: ,didUpdateLocations:)法吃收获位置后,常常会终止定位服务。之前在CLLocationManager中开创的那些变量非常适合处理当下之这种状况。

**明白了!** iOS 8模拟器在学Core
Location时会面世一些内外未均等的表现。如果固定服务没有调用,在Info.plist文件中上加三独键:
NSLocationWhenInUsageDescription NSLocationAlwaysUsageDescription
NSLocationUsageDescription 每个键对应之价设置成Always或者When in Use
这三只键值会拉扯打开定位服务

Core Location | Page 217

Map Kit

Map
Kit框架提供地图跟自由化,地图可以来得暨马路级别之信息,3D建筑,卫星图像,或者将两边结合起来。地图自动响应缩小、放大、平移、倾斜等手势动作,还会于地形图上标注点同时丰富注解。

MKMapView

Map
Kit提供MKMapView视图类来显示地图,MKMapView可以显得地图,管理用户的输入信息,展示起定义注释。

MKMapView也发一个delegate属性。和CLLocationManager的delegate属性一样,MKMapView的delegate也能接收updates。MKMapView
delegate需要按照MKMapViewDelegate协议。设置delegate的办法是,从Storyboard的Editor中,将Map
View用Control拖动法拖动到Document Outline中的View
Controller文字上,然后弹出一个菜系,点击菜单中的delegate,这样就于连锁界面上安装好了delegate。

MKMapView有广大便于之性能和法。举了例子,MKMapView不用添加其它代码就可以在地形图及显得用户地理位置。我们管性能设置showsUserLocationtrue,就可在地图上显示用户信息了:

myMapView.showsUserLocation = true

用户之职将会晤在地图上就此一个蓝点标注出来。

诚如我们拿用户所在位置设置为地图的主导点。如果想挪还安地图中心点,需要安装centerCoordinate属性,centerCoordinate性需要CLLocationCoordinate2DCLLocationCoordinate2D是经度和纬度的坐标,被起包改成一个单独的变量。通过CLLocationCoordinate2DMake主意创建CLLocationCoordinate2D

var coordinates: CLLocationCoordinate2D = CLLocationCoordinate2DMake(100,100)

突发性我们见面当地图上拓宽位置,当region特性设置好后,放大后图像会自行调整。region性能需要MKCoordinateRegion目标,然而,大部分状况下,比打创建新的对象,编辑时之region对象见面更简短有:

var updatedRegion: MKCoordinateRegion = myMapView.region
updatedRegion.span.longitudeDelta = updatedRegion.span.longitudeDelta * 2.0
updatedRegion.span.latitudeDelta = updatedRegion.span.latitudeDelta * 2.0 
myMapView.region = updatedRegion

Page 218 | Chapter 8 : Maps and Location

longitudeDeltalatitudeDelta犹是span的均等组成部分,span是面积有多万分,以centerCoordinate为主导而展示的增长率和可观。

Directions (方向)

Map Kit还能以App中提供建议计划路线导航功能。MKDirections
API可以依据苹果服务器的计量提供线路方向。有步行线路规划,驾驶线路规划,花费的光阴,和其它可选取的门路。地图上的每个点用MKMapItem表示,MKMapItem包含了地图上有关地方的享有消息,这些信包括地图位置,坐标值,地点名称等数码。MKMapItem还会传遍地图应用达到,使用地图应用上再度多高档功能。

创建MKMapItem最简单易行的点子是行使mapItemForCurrentLocation方,这个方式获得用户的位置然后因职务创建MKMapItem:

var mapItem: MKMapItem = MKMapItem.mapItemForCurrentLocation()

MKMapItem类有一对好的性能。name属性是一个字符串,提供地方的描述性名称。phoneNumber属性也是字符串,存储这个岗位的电话号码。URL属性存储位置的网址。

MKMapItem创建后,就好轻松的拿岗位传递至地图应用及,使用导航功能。openMapWithItems: launchOptions艺术可接一个往往组,数组中包括总括同交多只之MKMapItem。通过launchOptions,这么几items就见面为射到地图应用上。MKLaunchOptionsDirectionsModeKey于地图应用基于两独点来供设计路线。

Plotting Points (绘制点、标注点)

苹果商店提供了一个当地形图上绘制点的方,叫annotations(注解)。annotations是可定义一个地方要一个碰。它经常用于突出感兴趣之地方,提供再多细节。annotations也兼具一个可是选标注气泡(optional
callout
bubble)。气泡代表有职位的名跟地址那样的音。气泡也是只是点击的,可以像button(按钮)那样接收用户的动作。

annotations由简单片段构成,注解对象(annotation
object)和注释视图(annotation view)。annotation
object是一个轻量级对象,管理annotation中的数目。annotation
object是自从MKPointAnnotation类中创造的。annotation
view是从MKPinAnnotationView类中创造的。annotation
view用来以地图上标pin(大头针)。

Map Kit | Page 219

老三单步将annotation添加到MKMapView中。第一步是吧感谢兴趣之地址创建一个MKPointAnnotation:

var point = MKPointAnnotation()
point.coordinate = CLLocationCoordinate2DMake(37.7756, -122.4193)
point.title = "San Francisco"

接下来,遵循MKMapView协议,回应mapView(_: viewForAnnotation:)办法,此道好回收利用annotation
view,就像是table view中吗起方法可以还利用cell:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!)-> MKAnnotationView! {
    var pin = MKPinAnnotationView(annotation: annotation, reuseIdentifier:"pinIdentifier")
    return pin
}

最后,调用addAnnotation道,这样,就拿annotation添加到地图中了:

mapView.addAnnotation(point)

现在,我们来打定你首先独下了地图App吧。

Exercise: Adding Maps to the Passport App

练习请见是链接

Page 220| Chapter 8 : Maps and Location

相关文章