iOS应用程序背景位置(推送通知)

时间:2022-07-10 01:26:49

I face an issue where my app requires the users location when they receive a push notification while the app is running in the background.

我遇到一个问题,当应用程序在后台运行时,我的应用程序在收到推送通知时需要用户位置。

After doing a bit of reading I'm under the impression that this isn't possible, i.e:

在做了一些阅读后,我觉得这是不可能的,即:

1) App in background

1)应用程序在后台

2) Push notification received

2)收到推送通知

3) Get users location and execute block of code.

3)获取用户位置并执行代码块。

I found this post on here that suggests you can run a task every N amount of minutes to get the users location. So using this I could check say every ten minutes which would work but it would be a waste of the users battery if I kept activating the GPS. Therefore I was wondering can I tell within my background task if the user has any push notification waiting for my app? That way I would check if they did every ten minutes and only activate the GPS if they did.

我在这里发现了这篇文章,建议你可以每N分钟运行一次任务来获取用户位置。所以使用这个我可以检查说每十分钟可以工作,但如果我继续激活GPS将浪费用户电池。因此,我想知道我可以在后台任务中告诉用户是否有任何推送通知等待我的应用程序?这样我会检查他们是否每十分钟做一次,如果他们这样做,只会激活GPS。

Perhaps I'm going about this all the wrong way, I would really appreciate any advice. Sorry for not having any of the code for the background task yet as I'm still trying to get it to work.

也许我会以错误的方式解决这个问题,我真的很感激任何建议。很抱歉没有任何后台任务的代码,因为我仍然试图让它工作。

[UPDATE]

[UPDATE]

Thanks Dustin for your advice. After a bit of testing I've decided to go with an easier option. I am now using the Apple Significant Location Changes. I store the changes in an array, I've set this to only update if the last change was greater than 10min ago. Then when the app becomes active I match the closest time in the array to the time the push notification was sent and use that location.

感谢Dustin的建议。经过一些测试后,我决定采用更简单的选择。我现在正在使用Apple重要位置更改。我将更改存储在一个数组中,我将其设置为仅在最后一次更改大于10分钟前更新。然后,当应用程序变为活动状态时,我将数组中最接近的时间与发送推送通知的时间进行匹配并使用该位置。

1 个解决方案

#1


1  

As discussed I used alternative solution, here it is:

正如所讨论的,我使用了替代解决方案,这里是:

Under viewDidLoad or didFinishingLaunchingWithOptions add:

在viewDidLoad或didFinishingLaunchingWithOptions下添加:

locationsLogged = [[NSMutableArray alloc] init];
lastLocationTime = [[NSDate alloc] init]
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

Under applicationDidEnterBackground add:

在applicationDidEnterBackground下添加:

[locationManager startMonitoringSignificantLocationChanges];

Add:

加:

-(void) storeLocations:(CLLocation *)location
{
bgTask = [[UIApplication sharedApplication]
          beginBackgroundTaskWithExpirationHandler:
          ^{
              [[UIApplication sharedApplication] endBackgroundTask:bgTask];
               }];

[locationsLogged addObject:location];

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


 -(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
BOOL isInBackground = NO;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
    isInBackground = YES;
} 


NSDate *now = [NSDate date];
NSTimeInterval diff = [now timeIntervalSinceDate:lastLocationTime];


if ((int)diff > 600) {

    if (isInBackground)
    {
        [lastLocationTime release];
        lastLocationTime = [[NSDate alloc] init];
        [self storeLocations:newLocation];
    }
    else
    {
        // ...
    }
}
}

Then on applicationDidBecomeActive you can use whatever logic you need to apply location information.

然后在applicationDidBecomeActive上,您可以使用您需要的任何逻辑来应用位置信息。

#1


1  

As discussed I used alternative solution, here it is:

正如所讨论的,我使用了替代解决方案,这里是:

Under viewDidLoad or didFinishingLaunchingWithOptions add:

在viewDidLoad或didFinishingLaunchingWithOptions下添加:

locationsLogged = [[NSMutableArray alloc] init];
lastLocationTime = [[NSDate alloc] init]
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

Under applicationDidEnterBackground add:

在applicationDidEnterBackground下添加:

[locationManager startMonitoringSignificantLocationChanges];

Add:

加:

-(void) storeLocations:(CLLocation *)location
{
bgTask = [[UIApplication sharedApplication]
          beginBackgroundTaskWithExpirationHandler:
          ^{
              [[UIApplication sharedApplication] endBackgroundTask:bgTask];
               }];

[locationsLogged addObject:location];

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


 -(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
BOOL isInBackground = NO;
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
    isInBackground = YES;
} 


NSDate *now = [NSDate date];
NSTimeInterval diff = [now timeIntervalSinceDate:lastLocationTime];


if ((int)diff > 600) {

    if (isInBackground)
    {
        [lastLocationTime release];
        lastLocationTime = [[NSDate alloc] init];
        [self storeLocations:newLocation];
    }
    else
    {
        // ...
    }
}
}

Then on applicationDidBecomeActive you can use whatever logic you need to apply location information.

然后在applicationDidBecomeActive上,您可以使用您需要的任何逻辑来应用位置信息。