アプリがバックグラウンド モードのときに、アプリの現在の場所をサーバーに送信しようとしているのを助けてください。
しかし、しばらくすると、位置更新メソッドは現在の位置を取得するために停止します。
- (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];
[locationManager startMonitoringSignificantLocationChanges];
}
}
}
- (void)stopLocationTracking {
NSLog(@"stopLocationTracking");
if (self.shareModel.timer) {
[self.shareModel.timer invalidate];
self.shareModel.timer = nil;
}
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
}
#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:60 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];
[locationManager stopMonitoringSignificantLocationChanges];
NSLog(@"locationManager stop Updating after 10 seconds");
}
- (void)locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error
{
NSLog(@"locationManager error:%@",error);
}
//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];
}
[self getUpdateLocation];
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];
}
-(void)getUpdateLocation
{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
dataMobile = [currentDefaults valueForKey:@"mobile"];
dataCode = [currentDefaults valueForKey:@"code"];
strMobile = [self getDecryptionMobile];
strCode = [self getDecryptionCode];
strToken = [NSString stringWithFormat:@"%@%@%@",@"Apple",strMobile,strCode];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSDictionary *params = @ {@"function" :@"map/location/insert",@"childIdEnc":[currentDefaults valueForKey:@"childIdEnc"], @"phoneId" : [currentDefaults valueForKey:@"phoneId"], @"latitude": [NSString stringWithFormat:@"%f",self.myLocation.latitude], @"longitude": [NSString stringWithFormat:@"%f",self.myLocation.longitude]};
NSLog(@"params %@",params);
[manager POST:@"https://api.familyconnect.net/call/?debug=1" parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *jsonList = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
NSLog(@"JSON: %@", jsonList);
}
failure:
^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
アプリでバックグラウンド フェッチと位置情報の更新を使用しています。また、設定 - >機能からオンにします。
しかし、xcodeからデバッグしてバックグラウンドでアプリを取得すると、正常に動作しますが、切断してテストすると、場所の更新が停止します。
みんな助けてください。