苹果原生地图API封装
//
// HYBLocationManager.h
// MMLocationManager
//
// Created by sixiaobo on 14-7-17.
// Copyright (c) 2014年 Chen Yaoqiang. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "HYBSuperBaseViewController.h"
/*!
* @brief 地图相关功能封装类,提供获取地理坐标功能、获取地理坐标和地址功能、获取地址功能、
* 获取城市功能
*/
@interface HYBLocationManager : NSObject <MKMapViewDelegate>
// 定位时会加载到此mapView上,但Frame是CGRectZero,所以如果要显示此视图,需要在外部手动修改
@property (nonatomic, strong) MKMapView *mapView;
// 最近一次保存下来的用户的地理位置(经纬度)
@property (nonatomic, assign) CLLocationCoordinate2D latestCoordinate;
// 最近一次保存下来的cityid,格式为@"1,1,0",分别是省ID,市ID,区ID,其中区ID如果没有,则可设置为0
@property (nonatomic, copy) NSString *latestCityID;
// 最近一次保存下来的库存地址,如北京省|北京市|朝阳区(非定位得到)
// 最近一次在保存下来的地址信息,这个是通过定位得到的信息,(下面的是定位得到)
// 如,
// 1、直辖市:@"北京市|北京市",
// 2、自治区的:@"广西壮族自治区|南宁市",
// 3、正常省份:@"广东省|中山市"
@property (nonatomic, copy) NSString *latestStockAddress;
@property (nonatomic, assign) BOOL isUsingLocation; // 是否是通过定位的
// 是否是用户选择了取消台允许用户访问用户位置
@property (nonatomic, assign) BOOL isDeniedToAccessLocation;
// 转圈圈显示需要的时候,就需要传这个参数
@property (nonatomic, weak) HYBSuperBaseViewController *showNetworkStateInController;
// 单例方法
+ (HYBLocationManager *)sharedLocation;
/*!
* @brief 获取地理坐标
* @param locationCoordinateBlock 获取到的地理坐标信息会在这个block中返回
*/
// lc2d 即是定位到的地理坐标
typedef void (^HYBLocateCoordinateBlock)(CLLocationCoordinate2D lc2d);
- (void)locateCoordinate:(HYBLocateCoordinateBlock)locateCoordinateBlock;
/*!
* @brief 获取坐标和地址
* @param coordinateBlock 获取到的地理坐标信息会在这个block中返回
* @param addressBlock 获取到的地址信息
*/
// lc2d 即是定位到的地理坐标
typedef void (^HYBAddressBlock)(NSString *address);
- (void)locateCoordinate:(HYBLocateCoordinateBlock)coordinateBlock
address:(HYBAddressBlock)addressBlock;
/*!
* @brief 获取地址
* @param addressBlock 获取到的地址信息
*/
typedef void (^HYBLocationErrorBlock) (NSError *error);
- (void)locateAddress:(HYBAddressBlock)addressBlock error:(HYBLocationErrorBlock)errorBlock;
@end
//
// HYBLocationManager.m
// MMLocationManager
//
// Created by sixiaobo on 14-7-17.
// Copyright (c) 2014年 Chen Yaoqiang. All rights reserved.
//
#import "HYBLocationManager.h"
#define kLatestLongitude @"kLatestLongitudeKey" // 最新一次保存的纬度
#define kLatestLatitude @"kLatestLatitudeKey" // 最新一次保存的经度
#define kLatestStockAddress @"kLatestStockAddress" // 最新一次保存的库存地址
#define kLatestCityID @"kLatestCityID" // 最新一次保存的地址
@interface HYBLocationManager ()
@property (nonatomic, copy) HYBLocateCoordinateBlock locateCoordinateBlock;
@property (nonatomic, copy) HYBAddressBlock addressBlock;
@property (nonatomic, copy) HYBLocationErrorBlock errorBlock;
@end
@implementation HYBLocationManager
+ (HYBLocationManager *)sharedLocation {
static HYBLocationManager *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!sharedManager) {
sharedManager = [[[self class] alloc] init];
}
});
return sharedManager;
}
- (id)init {
if (self = [super init]) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.latestStockAddress = [defaults objectForKey:kLatestStockAddress];
self.latestCityID = [defaults objectForKey:kLatestCityID];
if (self.latestStockAddress == nil || self.latestCityID) {
self.latestStockAddress = @"北京市|朝阳区";
self.latestCityID = @"1,1,0"; // 北京省|北京市|朝阳区
[defaults setObject:self.latestStockAddress forKey:kLatestStockAddress];
[defaults setObject:self.latestCityID forKey:kLatestCityID];
[defaults synchronize];
}
float longtitude = [defaults floatForKey:kLatestLongitude];
float latitude = [defaults floatForKey:kLatestLatitude];
self.latestCoordinate = CLLocationCoordinate2DMake(latitude, longtitude);
self.isDeniedToAccessLocation = NO;
}
return self;
}
/*!
* @brief 获取地理坐标
* @param locationCoordinateBlock 获取到的地理坐标信息会在这个block中返回
*/
- (void)locateCoordinate:(HYBLocateCoordinateBlock)locateCoordinateBlock {
self.locateCoordinateBlock = [locateCoordinateBlock copy];
[self startLocating];
return;
}
/*!
* @brief 获取坐标和地址
* @param coordinateBlock 获取到的地理坐标信息会在这个block中返回
* @param addressBlock 获取到的地址信息
*/
- (void)locateCoordinate:(HYBLocateCoordinateBlock)coordinateBlock
address:(HYBAddressBlock)addressBlock {
self.locateCoordinateBlock = [coordinateBlock copy];
self.addressBlock = [addressBlock copy];
[self startLocating];
return;
}
/*!
* @brief 获取地址
* @param addressBlock 获取到的地址信息
*/
- (void)locateAddress:(HYBAddressBlock)addressBlock error:(HYBLocationErrorBlock)errorBlock {
self.addressBlock = [addressBlock copy];
self.errorBlock = [errorBlock copy];
[self startLocating];
return;
}
#pragma mark - Private
// 启动定位
- (void)startLocating {
if (self.mapView) { // 每次定位时先销毁之前的
self.mapView.delegate = nil;
self.mapView = nil;
}
self.mapView = [[MKMapView alloc] init];
self.mapView.delegate = self;
self.mapView.showsUserLocation = YES; // 打开定位功能
return;
}
// 停止定位
- (void)stopLocation {
_mapView.showsUserLocation = NO;
_mapView.delegate = nil;
_mapView = nil;
return;
}
- (void)setLatestCityID:(NSString *)lastestCityID {
if (_latestCityID != lastestCityID) {
_latestCityID = nil;
_latestCityID = [lastestCityID copy];
}
[kUserDefaults setObject:_latestCityID forKey:kLatestCityID];
[kUserDefaults synchronize];
return;
}
- (void)setLatestStockAddress:(NSString *)latestStockAddress {
if (_latestStockAddress != latestStockAddress) {
_latestStockAddress = nil;
_latestStockAddress = [latestStockAddress copy];
}
[kUserDefaults setObject:latestStockAddress forKey:kLatestStockAddress];
[kUserDefaults synchronize];
return;
}
#pragma mark - MKMapViewDelegate
- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView {
NSLog(@"开始定位");
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
if ([self.showNetworkStateInController respondsToSelector:@selector(startNetworkAnimating)]) {
[self.showNetworkStateInController startNetworkAnimating];
}
return;
}
- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView {
NSLog(@"停止定位");
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
if ([self.showNetworkStateInController respondsToSelector:@selector(stopNetworkAnimating)]) {
[self.showNetworkStateInController stopNetworkAnimating];
}
return;
}
// 定位失败处理
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
[self stopLocation];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
if (error.code == kCLErrorDenied) {
self.isDeniedToAccessLocation = YES;
}
if (self.errorBlock) {
self.errorBlock(error);
}
if ([self.showNetworkStateInController respondsToSelector:@selector(stopNetworkAnimating)]) {
[self.showNetworkStateInController stopNetworkAnimating];
}
return;
}
// 定位成功处理
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocation *newLocation = userLocation.location;
self.latestCoordinate = mapView.userLocation.location.coordinate;
NSUserDefaults *standard = [NSUserDefaults standardUserDefaults];
// 保存地理坐标
[standard setObject:@(self.latestCoordinate.longitude) forKey:kLatestLongitude];
[standard setObject:@(self.latestCoordinate.latitude) forKey:kLatestLatitude];
[[NSUserDefaults standardUserDefaults] synchronize];
// 地理编码器
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
// 地理位置反编码
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placeMark in placemarks) {
NSDictionary *addressDic = placeMark.addressDictionary;
for (NSString *value in addressDic.allValues) {
NSLog(@"value: %@", value);
}
NSString *state = [addressDic objectForKey:@"State"]; // 省份名称
NSString *city = [addressDic objectForKey:@"City"]; // 城市名称
NSString *district = [addressDic objectForKey:@"SubLocality"]; // 区
self.latestStockAddress = [NSString stringWithFormat:@"%@|%@|%@",
state, city ? city : state, district];
[standard setObject:self.latestStockAddress forKey:kLatestStockAddress];
[[NSUserDefaults standardUserDefaults] synchronize];
}
[self stopLocation];
if (self.locateCoordinateBlock) {
self.locateCoordinateBlock(self.latestCoordinate);
self.locateCoordinateBlock = nil;
}
if (self.addressBlock) {
self.addressBlock(self.latestStockAddress);
self.addressBlock = nil;
}
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
if ([self.showNetworkStateInController respondsToSelector:@selector(stopNetworkAnimating)]) {
[self.showNetworkStateInController stopNetworkAnimating];
}
}];
return;
}
@end
最后更新:2017-04-03 05:39:42