How to properly use location in background - app got rejected 3 times

佐手、 提交于 2019-12-18 12:33:47

问题


My app got rejected by Apple three times, all with the same rejection letter, which is:

We found that your app uses a background mode but does not include functionality that requires that mode to run persistently. This behavior is not in compliance with the App Store Review Guidelines.

We noticed your app declares support for location in the UIBackgroundModes key in your Info.plist but does not include features that require persistent location.

It would be appropriate to add features that require location updates while the app is in the background or remove the "location" setting from the UIBackgroundModes key.

If you choose to add features that use the Location Background Mode, please include the following battery use disclaimer in your Application Description:

"Continued use of GPS running in the background can dramatically decrease battery life."

For information on background modes, please refer to the section "Executing Code in the Background" in the iOS Reference Library.

Now, as far as I know I am running on the background and "doing something"... In my AppDelegate I have the following code in didFinishLaunchingWithOptions:

    if ([[launchOptions allKeys] containsObject:UIApplicationLaunchOptionsLocationKey] &&
    ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]))
{
    id locationInBackground = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
    if ([locationInBackground isKindOfClass:[CLLocation class]]) 
    {
        [self updateMyLocationToServer:locationInBackground];
    }
    else
    {
        //Keep updating location if significant changes
        CLLocationManager *locationManager = [[CLLocationManager alloc] init];
        self.bgLocationManager = locationManager;
        self.bgLocationManager.delegate = self;
        self.bgLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        [bgLocationManager startMonitoringSignificantLocationChanges];
    }
}

The AppDelegate also starts a location manager and makes himself the delegate. Then, I have the following code for handling the location updates on the background:

 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [self updateMyLocationToServer:newLocation];
}


-(void)updateMyLocationToServer:(CLLocation*)myNewLocation
{
    //    NSLog(@"Updating Location from the background");

    NSString *fbID = [NSString stringWithString:[facebookDetails objectForKey:@"fbID"]];
    NSString *firstName = [NSString stringWithString:[facebookDetails objectForKey:@"firstName"]];
    NSString *lastName = [NSString stringWithString:[facebookDetails objectForKey:@"lastName"]];

    NSString *urlString = [NSString stringWithFormat:@"MY_SERVER_API", fbID, myNewLocation.coordinate.latitude, myNewLocation.coordinate.longitude, firstName, lastName];


    NSURL *url = [NSURL URLWithString:urlString];

    __block ASIHTTPRequest *newRequest = [ASIHTTPRequest requestWithURL:url];

    [newRequest setCompletionBlock:^{


    }];

    [newRequest setFailedBlock:^{

    }];

    //    [newRequest setDelegate:self];
    [newRequest startAsynchronous];
}

I also put a disclaimer in my app description page:

Intensive use of GPS running in the background can dramatically decrease battery life. For this reason, MY_APP_NAME runs on the background just listening for significant location changes.

Is there anything I'm missing here?


回答1:


In locationManager:didUpdateToLocation:fromLocation: or in updateMyLocationToServer: You should check if application is in background state by eg.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

And then if Your app is in background mode You should use eg.

backgroundTask = [[UIApplication sharedApplication]
                    beginBackgroundTaskWithExpirationHandler:
                    ^{
                        [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
                    }];

/*Write Your internet request code here*/

if (bgTask != UIBackgroundTaskInvalid)
{
    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
    bgTask = UIBackgroundTaskInvalid;
}

This way application should perform this task completely.




回答2:


This question is old and already answered but you dont need the UIBackgroundModes key if you collect locations using the startMonitoringSignificantLocationChanges API




回答3:


startMonitoringSignificantLocationChanges don't require a background mode registration. Only continuous location changes do.



来源:https://stackoverflow.com/questions/10527935/how-to-properly-use-location-in-background-app-got-rejected-3-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!