由于項(xiàng)目的需要巍举,用到定位的功能脆荷,折騰了一下午,總算有個(gè)大概得了解了懊悯。
這里主要是用了CLLocationManager進(jìn)行定位蜓谋。使用分為以下幾個(gè)步驟:
1.導(dǎo)入相關(guān)的庫(kù)CoreLocation.frameWork
2.勾選開(kāi)啟后臺(tái)定位選項(xiàng)
3.此時(shí)在plist文件可以看到多了
4.在plist添加兩個(gè)參數(shù),允許應(yīng)用在使用期間定位炭分、或者在后臺(tái)也能繼續(xù)定位桃焕。
5.到這里為止,所有的界面配置完成捧毛。然后在AppDelegate.h類中導(dǎo)入頭文件
```
#import<CoreLocation/CoreLocation.h>
```
若是報(bào)錯(cuò)观堂,則證明在第一步中沒(méi)有導(dǎo)入相關(guān)的 CoreLocation.frameWork 庫(kù)。
在AppDelegate.m文件中有代理方法
```
@interface AppDelegate ()<CLLocationManagerDelegate>
```
然后在APPDelegate.h中聲明設(shè)置這些變量呀忧。
```
@property (strong,nonatomic)CLLocationManager * locationManager; // 創(chuàng)建工程的全部變量
@property (nonatomic,assign)BOOL executingInBackground;
@property (strong,nonatomic)NSTimer * timer; // 計(jì)時(shí)器
```
一般來(lái)說(shuō)师痕,locationManager定位只要一開(kāi)始,如果不[self.locationManager stopUpdatingLocation]而账,則會(huì)根據(jù)所在的位置是否超出多少米胰坟,不定時(shí)的更新定位。如果想要每隔一段時(shí)間進(jìn)行定位福扬。則需要開(kāi)啟一個(gè)計(jì)時(shí)器(timer)腕铸,然后每定位一次,立刻關(guān)掉定位铛碑。待計(jì)時(shí)器計(jì)算時(shí)間狠裹,再次觸發(fā)定位。在didFinishLaunchingWithOptions方法中:
```
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate = self;
//? ? self.locationManager.distanceFilter = 1.0; // 位置超過(guò)1米汽烦,就再次重新定位
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 定位精度最為準(zhǔn)確涛菠,越準(zhǔn)確,耗電量越大
//? ? [self.locationManager startUpdatingLocation];
self.locationManager.pausesLocationUpdatesAutomatically=NO;
if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
{
if(kIOSVersions>=8.0)
{
[self.locationManager requestAlwaysAuthorization];
[self.locationManager requestWhenInUseAuthorization];//使用程序其間允許訪問(wèn)位置數(shù)據(jù)(iOS8定位需要)
}
if(kIOSVersions>=9.0)
{
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
}
NSError *setCategoryErr = nil;
NSError *activationErr? = nil;
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryPlayback
error: &setCategoryErr];
[[AVAudioSession sharedInstance]
setActive: YES
error: &activationErr];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
[userDefault setValue:@"0" forKey:isShowTestEnvironment];
[userDefault setBool:NO forKey:USERDEFAULTS_IS_SAVE_ENVIRONMENT];
[userDefault synchronize];
```
以上代碼之所以沒(méi)有立刻開(kāi)啟定位,是想讓計(jì)時(shí)器觸發(fā)開(kāi)始定位俗冻。
6.應(yīng)用程序掉到后臺(tái)時(shí)候礁叔,執(zhí)行的方法:applicationDidEnterBackground
要想在后臺(tái)計(jì)時(shí)器能繼續(xù)計(jì)時(shí),則需要在此方法中添加
```
UIApplication*? app = [UIApplication sharedApplication];
__block? ? UIBackgroundTaskIdentifier bgTask;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
bgTask = UIBackgroundTaskInvalid;
}
});
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
bgTask = UIBackgroundTaskInvalid;
}
});
});
```
7.應(yīng)用在前臺(tái)是調(diào)用的方法:applicationWillEnterForeground
//當(dāng)應(yīng)用程序回到前臺(tái)時(shí)迄薄,執(zhí)行該方法
```
-(void)applicationWillEnterForeground:(UIApplication*)application
{
//程序進(jìn)入前臺(tái)琅关,轉(zhuǎn)化為高精確定位
self.executingInBackground = NO;
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
```
8.定位成功時(shí)候的回調(diào)方法:didUpdateToLocation
```
#pragma mark 定位成功回調(diào)
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (self.executingInBackground)
{ // 在后臺(tái)
if(kIOSVersions>=8.0)
{
[self.locationManager requestAlwaysAuthorization];
[self.locationManager requestWhenInUseAuthorization];//使用程序其間允許訪問(wèn)位置數(shù)據(jù)(iOS8定位需要)
}
if(kIOSVersions>=9.0)
{
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
NSLogS(@"后臺(tái)臺(tái)");
}else{
// 在前臺(tái)
NSLogS(@"前臺(tái)");
}
NSLog(@"經(jīng)度:%f", newLocation.coordinate.longitude+0.001253);
NSLog(@"緯度:%f", newLocation.coordinate.latitude-0.000182);
NSLog(@"速度:%f 米/秒", newLocation.speed);
CLGeocoder * geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSDictionary *locationInfo = [[NSDictionary alloc]init];
for (CLPlacemark * placemark in placemarks) {
locationInfo = [placemark addressDictionary];
}
NSLog(@"%@",locationInfo);
}];
```
[self.locationManager stopUpdatingLocation]; // 這里每定位一次,就關(guān)掉定位讥蔽,等待計(jì)時(shí)器再次觸發(fā)涣易。如果不關(guān)掉定位,則:
?? self.locationManager.distanceFilter = 1.0; // 兩者位置超過(guò)1米冶伞,就再次重新定位
根據(jù)這句話判斷是否重新定位新症。(需不需要關(guān)掉,看需求)
}
9.定位失敗的時(shí)候的回調(diào)方法
```
#pragma mark 定位失敗回調(diào)
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"error%@", error);
}
```
ps:這里我觸發(fā)定位的開(kāi)始是在MainMenuController類中做的响禽。(也就是一旦用戶登錄成功就開(kāi)始定位)
在MainMenuController類中:
說(shuō)得比較粗糙徒爹,望各位多多指點(diǎn),謝謝~
ps:在ios8系統(tǒng)中芋类,不知怎么的隆嗅,我退到后臺(tái)定位后,利用計(jì)時(shí)器調(diào)用觸發(fā)事件梗肝,只執(zhí)行了兩次就沒(méi)法點(diǎn)位了榛瓮,后來(lái)檢查了好久,發(fā)現(xiàn)計(jì)時(shí)器在后臺(tái)還一直計(jì)時(shí)巫击,被困擾了好久禀晓。最后,刪了app坝锰,重新再安裝粹懒,就可以了。真暈顷级,不知道是不是緩存的問(wèn)題凫乖。