如何知道iphone的物理位置,这一问题在LBS的应用中很常见。解决起来其实也很简单,就两步。第一步,通过CoreLocation获取经度纬度;第二步,通过google网络服务或者其他架构及获取经纬度以得到物理地址。
获取经度纬度的操作过程
首先,
添加CoreLocation.Frameworks,并将其头文件放在需要引用的类的头文件中,且在头文件中声明一个CLLocationManager类的属性对象。在头文件中@interface后加上<CLLocationManagerDelegate>;
其次,
在头文件中声明属性locationManager;
@property (nonatomic, weak) CLLocationManager *locationManager;
因为XCODE使用的是4.5版本,所以在implement文件中可以不加@synchronized locationManager;
最后,在实现文件中实现CLLocationManagerDelegate的必须实现的方法和CLLocationManager调用。
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager.delegate=self;
self.locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
}
委托CLLocationManagerDelegate中两个方法需要实现。
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
DebugLog(@"%f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
DebugLog(@"%@",error);
}
但是,在调试过程中,发现委托的方法并没有执行。在属性locationManager经过编译器设置的_locationManager已经在viewDidLoad执行结束后就释放了,所以,委托方法是不可能执行的。
两个解决方法,其一,调整属性设置,@property (nonatomic, strong) CLLocationManager *locationManager;其二,不要属性设置,自己在interface()中定义实例变量,再自己初始化。
因为默认对象的引用指针保留方式都是strong。
获取物理位置的操作过程
我们已经获取了经纬度,要知道物理位置,到经纬度与物理位置对应的数据库中去找即可。
获取经度纬度的操作过程
首先,
添加CoreLocation.Frameworks,并将其头文件放在需要引用的类的头文件中,且在头文件中声明一个CLLocationManager类的属性对象。在头文件中@interface后加上<CLLocationManagerDelegate>;
其次,
在头文件中声明属性locationManager;
@property (nonatomic, weak) CLLocationManager *locationManager;
因为XCODE使用的是4.5版本,所以在implement文件中可以不加@synchronized locationManager;
最后,在实现文件中实现CLLocationManagerDelegate的必须实现的方法和CLLocationManager调用。
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager.delegate=self;
self.locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;
[self.locationManager startUpdatingLocation];
}
委托CLLocationManagerDelegate中两个方法需要实现。
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
DebugLog(@"%f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
DebugLog(@"%@",error);
}
但是,在调试过程中,发现委托的方法并没有执行。在属性locationManager经过编译器设置的_locationManager已经在viewDidLoad执行结束后就释放了,所以,委托方法是不可能执行的。
两个解决方法,其一,调整属性设置,@property (nonatomic, strong) CLLocationManager *locationManager;其二,不要属性设置,自己在interface()中定义实例变量,再自己初始化。
因为默认对象的引用指针保留方式都是strong。
获取物理位置的操作过程
我们已经获取了经纬度,要知道物理位置,到经纬度与物理位置对应的数据库中去找即可。
方法很多中,通过google可以,http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true。但是google不幸被墙了,只能通过其他方式,有人说高德可以,也有人说第三方框架也可以。
On iOS 5 MKReverseGeoCoder is Deprecated!
So you want to use CLGeocoder with CLLocationManager, very simple and works with block.
Example:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[self.locationManager stopUpdatingLocation];
CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark * placemark in placemarks) {
.... = [placemark locality];
}
}];
}