位置管理器不更新位置ios7
Posted
技术标签:
【中文标题】位置管理器不更新位置ios7【英文标题】:Location manager not updating location ios7 【发布时间】:2014-02-24 00:47:52 【问题描述】:我正在尝试在服务器更新时(理想情况下每 100 米)将用户位置发送到服务器,但现在我只是想让它工作。我对 ios 7 很陌生,所以这可能并不像我想象的那么难……但这是我拥有的代码
-(void)sendUserLocationToServer
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = 10; //kCLDistanceFilterNone; // whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // The best you can get
[self.locationManager startUpdatingLocation];
NSLog(@"HELLO. Latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude);
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
NSLog(@"loactions %@", locations);
基本上,我有一个调用 sendUserLocationToServer 的方法来启动位置管理器,并且计划以某种方式使用 didUpdateLocations 方法,现在我只想注销该位置......但这就是我我到达那里后会拨打服务器电话。
在日志中,我看到了“HELLO”日志,但它从未归结为 didUpdateLocations 方法。
我错过了什么?
谢谢
编辑:不确定它是否有区别,但我在我的应用程序委托中有这个,它调用进程 pushPushNotificationData 方法
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)responseInfo
NSLog(@"Received Notification: %@", responseInfo);
//Import the class header where the function is in this file (see above)
//Set class to variable
//Init the varibale / class
//Add the method you want to make public in the headerfile of responderViewController
XYZResponderViewController *responderController;
responderController = [[XYZResponderViewController alloc] init];
[responderController processPushNotificationData:responseInfo];
【问题讨论】:
【参考方案1】:您需要为您的位置经理设置委托(查看 here 以获取文档)。
将此添加到您的经理的初始化中:
[locationManager setDelegate:self];
当然,“self”必须符合 CLLocationManagerDelegate 协议(查看here 以获取苹果的文档。
【讨论】:
我做到了...当我使用模拟器时它会更新,但是当我尝试在手机上运行它时它不起作用。 该应用是否启用了位置服务访问权限?也许当应用程序第一次运行时您没有授予此权限。 是的,它有权限......它使用“HELLO”和位置进入 NSLog......只是没有更新 另外,我做了 locationManager setDeegate:self...还是不行...我会更新我的代码【参考方案2】:我想有一个委托需要在某个地方设置。 locationManager:didUpdateLocations: 看起来像一个典型的委托方法。
【讨论】:
【参考方案3】:首先添加委托
@interface ViewController : UIViewController <CLLocationManagerDelegate>
然后当你在你的 .m 控制器中初始化它时,设置委托:
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
//[locationManager setDistanceFilter:10]; //kCLDistanceFilterNone; // whenever we move
[locationManager setDistanceFilter:kCLDistanceFilterNone]; // whenever we move
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; // The best you can get
[locationManager startUpdatingLocation];
我不知道这是否也是你需要的,但这就是我正在使用的......
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
float currentLocationLati = [[locations objectAtIndex:0] coordinate].latitude;
float currentLocationLong = [[locations objectAtIndex:0] coordinate].longitude;
NSLog(@"hAccuracy: %.1f, vAccuracy: %.1f", [[locations objectAtIndex:0] horizontalAccuracy], [[locations objectAtIndex:0] verticalAccuracy]);
NSLog(@"Locations %@", [locations objectAtIndex:0]);
【讨论】:
是的,我有...不起作用。 哦,我明白了!如果您之后使用以下内容怎么办? [responderController.locationManager startUpdatingLocation]; 这在我的 responderViewController 和应用委托中都引发了错误【参考方案4】:#import "LocationTracker.h"
#define LATITUDE @"latitude"
#define LONGITUDE @"longitude"
#define ACCURACY @"theAccuracy"
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
@implementation LocationTracker
AppDelegate *objApp;
+ (CLLocationManager *)sharedLocationManager
static CLLocationManager *_locationManager;
@synchronized(self)
if (_locationManager == nil)
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
return _locationManager;
- (id)init
if (self==[super init])
//Get the share model and also initialize myLocationArray
self.shareModel = [LocationShareModel sharedModel];
self.shareModel.myLocationArray = [[NSMutableArray alloc]init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
objApp = (AppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
-(void)applicationEnterBackground
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLDistanceFilterNone;
if(IS_OS_8_OR_LATER)
[locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
//Use the BackgroundTaskManager to manage all the background Task
self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];
- (void) restartLocationUpdates
NSLog(@"restartLocationUpdates");
if (self.shareModel.timer)
[self.shareModel.timer invalidate];
self.shareModel.timer = nil;
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLDistanceFilterNone;
if(IS_OS_8_OR_LATER)
[locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
- (void)startLocationTracking
NSLog(@"startLocationTracking");
if ([CLLocationManager locationServicesEnabled] == NO)
NSLog(@"locationServicesEnabled false");
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled" message:@"You currently have all location services for this device disabled" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[servicesDisabledAlert show];
else
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];
if(authorizationStatus == kCLAuthorizationStatusDenied || authorizationStatus == kCLAuthorizationStatusRestricted)
NSLog(@"authorizationStatus failed");
else
NSLog(@"authorizationStatus authorized");
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLDistanceFilterNone;
if(IS_OS_8_OR_LATER)
[locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
- (void)stopLocationTracking
NSLog(@"stopLocationTracking");
if (self.shareModel.timer)
[self.shareModel.timer invalidate];
self.shareModel.timer = nil;
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
[locationManager stopUpdatingLocation];
#pragma mark - CLLocationManagerDelegate Methods
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
NSLog(@"locationManager didUpdateLocations");
for(int i=0;i<locations.count;i++)
CLLocation * newLocation = [locations objectAtIndex:i];
CLLocationCoordinate2D theLocation = newLocation.coordinate;
CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 30.0)
continue;
//Select only valid location and also location with good accuracy
if(newLocation!=nil&&theAccuracy>0
&&theAccuracy<2000
&&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0)))
self.myLastLocation = theLocation;
self.myLastLocationAccuracy= theAccuracy;
NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
[dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
[dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
[dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
//Add the vallid location with good accuracy into an array
//Every 1 minute, I will select the best location based on accuracy and send to server
[self.shareModel.myLocationArray addObject:dict];
//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
return;
self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];
//Restart the locationMaanger after 1 minute
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:30 target:self
selector:@selector(restartLocationUpdates)
userInfo:nil
repeats:NO];
//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
if (self.shareModel.delay10Seconds)
[self.shareModel.delay10Seconds invalidate];
self.shareModel.delay10Seconds = nil;
self.shareModel.delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self
selector:@selector(stopLocationDelayBy10Seconds)
userInfo:nil
repeats:NO];
//Stop the locationManager
-(void)stopLocationDelayBy10Seconds
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
[locationManager stopUpdatingLocation];
NSLog(@"locationManager stop Updating after 10 seconds");
- (void)locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error
// NSLog(@"locationManager error:%@",error);
switch([error code])
case kCLErrorNetwork: // general, network-related error
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network Error" message:@"Please check your network connection." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
break;
case kCLErrorDenied:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Enable Location Service" message:@"You have to enable the Location Service to use this App. To enable, please go to Settings->Privacy->Location Services" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
break;
default:
break;
//Send the location to Server
- (void)updateLocationToServer
NSLog(@"updateLocationToServer");
// Find the best location from the array based on accuracy
NSMutableDictionary * myBestLocation = [[NSMutableDictionary alloc]init];
for(int i=0;i<self.shareModel.myLocationArray.count;i++)
NSMutableDictionary * currentLocation = [self.shareModel.myLocationArray objectAtIndex:i];
if(i==0)
myBestLocation = currentLocation;
else
if([[currentLocation objectForKey:ACCURACY]floatValue]<=[[myBestLocation objectForKey:ACCURACY]floatValue])
myBestLocation = currentLocation;
NSLog(@"My Best location:%@",myBestLocation);
//If the array is 0, get the last location
//Sometimes due to network issue or unknown reason, you could not get the location during that period, the best you can do is sending the last known location to the server
if(self.shareModel.myLocationArray.count==0)
NSLog(@"Unable to get location, use the last known location");
self.myLocation=self.myLastLocation;
self.myLocationAccuracy=self.myLastLocationAccuracy;
else
CLLocationCoordinate2D theBestLocation;
theBestLocation.latitude =[[myBestLocation objectForKey:LATITUDE]floatValue];
theBestLocation.longitude =[[myBestLocation objectForKey:LONGITUDE]floatValue];
self.myLocation=theBestLocation;
self.myLocationAccuracy =[[myBestLocation objectForKey:ACCURACY]floatValue];
NSLog(@"Send to Server: Latitude(%f) Longitude(%f) Accuracy(%f)",self.myLocation.latitude, self.myLocation.longitude,self.myLocationAccuracy);
//TODO: Your code to send the self.myLocation and self.myLocationAccuracy to your server
//After sending the location to the server successful, remember to clear the current array with the following code. It is to make sure that you clear up old location in the array and add the new locations from locationManager
[self.shareModel.myLocationArray removeAllObjects];
self.shareModel.myLocationArray = nil;
self.shareModel.myLocationArray = [[NSMutableArray alloc]init];
@end
【讨论】:
我希望这段代码对你有用。我已经尝试了许多位置管理器的代码。这个最准确。以上是关于位置管理器不更新位置ios7的主要内容,如果未能解决你的问题,请参考以下文章