简体   繁体   English

在iOS中后台运行应用程序时将用户位置发送到服务器

[英]Send user location to server while app in background in ios

Please help me i am trying to send my current location of app to server while my app is in background mode. 请帮我,我正在尝试将我当前的应用位置发送到服务器,而我的应用处于后台模式。

But after some time location update method is stops to get current location. 但是一段时间后,位置更新方法将停止以获取当前位置。

- (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);
     }];
}

I have use background fetch and location update in my app. 我在我的应用中使用了后台抓取和位置更新。 also turn on it from settings->capabilities. 也可以通过设置->功能将其打开。

But when i am debugging from xcode and get app in background then its working properly but while i disconnect and test it then its stops updating my location. 但是,当我从xcode调试并在后台获取应用程序时,它可以正常工作,但是当我断开连接并对其进行测试时,它停止更新我的位置。

Please help me guys. 请帮助我。

It seems you are using code inspired by this example https://github.com/voyage11/Location 似乎您正在使用受此示例启发的代码https://github.com/voyage11/Location

But this example stops the location updates after 10 seconds in order to save battery life. 但是此示例将在10秒后停止位置更新,以节省电池寿命。 See this comment 查看此评论

//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

But if configured correctly, the locationtracker also creates a timer in order to start the location updates again in 60 seconds. 但是,如果配置正确,locationtracker还会创建一个计时器,以便在60秒内再次开始位置更新。

Basically it collects location updates for 10 seconds, filters out the best. 基本上,它会收集位置更新10秒钟,以过滤出最佳位置。 After 60 seconds location updates are starting again. 60秒后,位置更新将再次开始。 In the link above please refere to the LocationAppDelegate calls 在上面的链接中,请参考LocationAppDelegate调用

//Send the best location to server every 60 seconds
//You may adjust the time interval depends on the need of your app.
NSTimeInterval time = 60.0;
self.locationUpdateTimer =
[NSTimer scheduledTimerWithTimeInterval:time
                                 target:self
                               selector:@selector(updateLocation)
                               userInfo:nil
                                repeats:YES];

This timer leads to a "restart" of the location updates. 该计时器导致位置更新的“重启”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在后台模式下,如何在iOS5上获取用户位置? - How to get user location on iOS5 while app in background mode? 迅速,当应用程序被杀死时将用户的当前位置发送到服务器 - In swift, send User’s current location to server while app is killed iOS:在手机锁定且应用处于后台/挂起状态时,将心跳发送到服务器 - iOS: send heartbeat to the server while phone is locked and the app is on the background/suspended 在iOS中处于后台时跟踪用户的位置 - Tracking the user's location while in background in iOS 如何定期获取位置并将位置发送到后台ios9中的服务器 - How to get location periodically and send location to server in background ios9 当app在后台时,我可以将用户的当前位置发送到服务器吗? - Can I send user's current location to server, when app is in background? 当应用程序处于后台时,如何从ios 5应用程序向本地网络中的服务器发送一些请求? - How can i send some request from ios 5 app to server who is in local network, while app is in background? 向应用程序发送静默推送通知,更新位置并在后台发送到服务器 - Send silent push notification to app, update location and send to server in background 应用程序位置在iOS 8的后台 - App location in background on iOS 8 iOS:当应用在后台运行一段时间后,停止位置更新 - IOS: Stop location updates when app is in the background for a while
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM