在iOS中提供定位功能的框架是CoreLocation,框架中提供了一个位置管理器(CLLoctionManager),想要使用这个管理器,它就必须是全局的。位置管理器提供了大部分的位置功能,通过设置位置管理器的参数来调整位置的精度和位置刷新的频率。实现位置管理器的代理方法就能获得所要的位置参数。
首先,在TARGETS中的Build Phases中添加CoreLocation框架,然后在info.plist文件中添加两个成员:NSLocationAlwaysUsageDescription ,NSLocationWhenInUseUsageDescription,值可以为空,也可以为YES。
为了使用的方便,将定位功能的位置管理器子类化(继承自NSObject),设置好代理:CLLocationManagerDelegate,然后创建一个全局的位置管理器:loctionmanager,这个管理器只要一个就好了,所以创建单例就可以了。具体代码:
#import <CoreLocation/CoreLocation.h>
<pre name="code" class="objc">#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#define CCLastLongitude @"CCLastLongitude"#define CCLastLatitude @"CCLastLatitude"#define CCLastCity @"CCLastCity"#define CCLastAddress @"CCLastAddress"typedef void (^LocationBlock)(CLLocationCoordinate2D locationCorrrdinate);typedef void (^LocationErrorBlock) (NSError *error);typedef void(^NSStringBlock)(NSString *cityString);typedef void(^NSStringBlock)(NSString *addressString);@interface CCLocationManager : NSObject<CLLocationManagerDelegate>
@property (nonatomic) CLLocationCoordinate2D lastCoordinate;
@property(nonatomic,strong)NSString *lastCity;
@property (nonatomic,strong) NSString *lastAddress;
@property(nonatomic,assign)float latitude;
@property(nonatomic,assign)float longitude;
+ (CCLocationManager *)shareLocation;
//一下方法就是将block赋值,然后在代理方法中回调即可。
/*
* 获取坐标
*/
- (void) getLocationCoordinate:(LocationBlock) locaiontBlock ;
/*
* 获取坐标和详细地址
*/
- (void) getLocationCoordinate:(LocationBlock) locaiontBlock withAddress:(NSStringBlock) addressBlock;
/*
* 获取详细地址
*/
- (void) getAddress:(NSStringBlock)addressBlock;
/*
* 获取城市
*/
- (void) getCity:(NSStringBlock)cityBlock;
/*
* 获取城市和定位失败
*/
- (void) getCity:(NSStringBlock)cityBlock error:(LocationErrorBlock) errorBlock;
使用定位之前,还要先开启定位:
-(void)startLocation
{
if([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
{
_manager=[[CLLocationManager alloc]init];
_manager.delegate=self;
_manager.desiredAccuracy = kCLLocationAccuracyBest;
[_manager requestAlwaysAuthorization];
_manager.distanceFilter=100;
[_manager startUpdatingLocation];
}
else
{
UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"提示" message:@"需要开启定位服务,请到设置->隐私,打开定位服务" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
[alertView show];
}
}
接着在代理方法中有一个方法可以获取位置:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSUserDefaults *standard = [NSUserDefaults standardUserDefaults];
CLGeocoder *geocoder=[[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks,NSError *error)
{
if (placemarks.count > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
_lastCity = [NSString stringWithFormat:@"%@%@",placemark.administrativeArea,placemark.locality];
[standard setObject:_lastCity forKey:CCLastCity];//省市地址
NSLog(@"______%@",_lastCity);
_lastAddress = [NSString stringWithFormat:@"%@%@%@%@%@%@",placemark.country,placemark.administrativeArea,placemark.locality,placemark.subLocality,placemark.thoroughfare,placemark.subThoroughfare];//详细地址
NSLog(@"______%@",_lastAddress);
}
if (_cityBlock) {
_cityBlock(_lastCity);
_cityBlock = nil;
}
if (_addressBlock) {
_addressBlock(_lastAddress);
_addressBlock = nil;
}
}];
_lastCoordinate = CLLocationCoordinate2DMake(newLocation.coordinate.latitude ,newLocation.coordinate.longitude );
if (_locationBlock) {
_locationBlock(_lastCoordinate);
_locationBlock = nil;
}
NSLog(@"%f--%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
[standard setObject:@(newLocation.coordinate.latitude) forKey:CCLastLatitude];
[standard setObject:@(newLocation.coordinate.longitude) forKey:CCLastLongitude];
[manager stopUpdatingLocation];
}
在使用中,由于在iOS8以后使用定位功能要需要得到用户的授权,所以有如下代码(都是对位置管理器的设置):
if (IS_IOS8) {
locationmanager = [[CLLocationManager alloc] init];
[locationmanager requestAlwaysAuthorization];
[locationmanager requestWhenInUseAuthorization];
locationmanager.delegate = self;
}
最后就可以调用locationmanager中的getLocation一些方法获取位置。