最近再练习使用高德地图和百度地图的时候突然想到,以后的项目中非常有可能用到定位的功能,而定位功能的时候免不了使用各种API,但是如果每一次做项目就重写定位的方法未免有点愚蠢,于是就自己动手用高德的api封装了一个用户定位的类,以供自己以后使用。
本篇博文对高德api的导入就不再进行赘述,直接开始对LocationTool的封装,以下是封装的思路。
1.考虑到一个APP中即便进行多次定位也没有必要创建多个工具类的实例对象,因此就使用了单例设计模式。首先,在implementation后面,声明一个静态全局对象,无论定位工具类实例化多少次,返回的永远都是这一个静态对象。接下来就是重写allocWithZone:zone函数,利用c语言的函数dispatch_once_t来创建单例对象主要是考虑到线程安全问题。之后利用工厂模式写一个静态方法来快速创建工具类实例对象。
static LocationTool *_locationTool;
+(id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_locationTool = [super allocWithZone:zone];
});
return _locationTool;
}
+(LocationTool *)shareLocaionTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_locationTool = [[self alloc]init];
});
return _locationTool;
}
-(id)init
{
if (self = [super init]) {
[MAMapServices sharedServices].apiKey = (NSString *)APIKey;
self.mapView = [[MAMapView alloc]init];
self.searchAPI = [[AMapSearchAPI alloc] initWithSearchKey:(NSString *)APIKey Delegate:self];
self.mapView.showsUserLocation = YES;
self.mapView.userTrackingMode = MAUserTrackingModeFollowWithHeading;
}
return self;
}
2.接下来就是在LocationTool类中实现定位的功能,大致的思路是利用高德地图中创建MAMapView对象和AMapSearchAPI对象,然后利用MAMapVIew获取用户的经纬度坐标,然后再利用AMapSearchAPI对象,设置代理为SELF,进行逆地理编码,然后就能在AMapSearchAPI代理方法中获取respones,之后便能获取用户地址的位置了。(高德官方指南有示例过程.)
-(void)searchLocationReGeocode
{
NSLog(@"开始地理逆向编码!");
AMapReGeocodeSearchRequest *request = [[AMapReGeocodeSearchRequest alloc]init];
request.searchType = AMapSearchType_ReGeocode;
request.location = [AMapGeoPoint locationWithLatitude:(float)self.mapView.userLocation.location.coordinate.latitude longitude:(float)self.mapView.userLocation.location.coordinate.longitude];
NSLog(@"%f,%f",self.mapView.userLocation.location.coordinate.latitude,self.mapView.userLocation.location.coordinate.longitude);
request.requireExtension = NO;
[self.searchAPI AMapReGoecodeSearch:request];
}
-(void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
NSLog(@"dsadsad");
if (response != nil) {
_userLocation = [NSString stringWithFormat:@"%@",response.regeocode.addressComponent.province];
NSLog(@"%@",_userLocation);
}
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:_userLocation message:@"是否将上面的地址作为您的地址?" delegate: self cancelButtonTitle:@"你在瞎定位!" otherButtonTitles:@"就是这个!", nil];
[alertView show];
}
3.利用代理设计模式,降低代码的耦合性,以供以后的项目使用。以下是工具类的.h文件。
@protocol LocationToolDelegate;
@interface LocationTool : NSObject <AMapSearchDelegate,UIAlertViewDelegate,MAMapViewDelegate>
@property (nonatomic,assign) id <LocationToolDelegate> delegate;
@property (nonatomic,strong) MAMapView *mapView;
@property (nonatomic,strong) AMapSearchAPI *searchAPI;
@property (nonatomic) CLLocationCoordinate2D coordinate;
+(LocationTool *)shareLocaionTool;
-(void)searchLocationReGeocode;
@end
@protocol LocationToolDelegate <NSObject>
-(void)settingLocationWithAddress:(NSString *)address;
@end