我正在通过重新启动应用程序的后台API测试位置更新。我已经成功测试了访问和地区,并且正在使用同一应用程序还测试了重大的LocationChanges(SLC)。我运行我的应用程序,按两次主屏幕,然后将其擦除以将其杀死。然后我开车转转。我可以观察到应用程序的后台活动,而无需通过服务器触摸手机,在该服务器中(参见下面的代码)单例方法sendBackgroundTestRecord将简单的状态消息上传到服务器。

当我测试访问和地区时,我没有问题。但是,当我测试SLC时,直到打开手机屏幕(按一下电源或主页按钮-不会重新运行该应用程序,甚至不会解锁手机)都不会发生。我可以开车很远的地方,什么都没发生。我怀疑该应用在该驱动器中的某个时间收到了SLC事件,因为一旦我打开手机大约2秒钟,下面的代码就会执行,并且我可以观察服务器上的消息。

我相信这不仅是网络连接延迟,因为sendBackgrounTestRecord方法使用时间戳。服务器上的记录显示的时间戳记是我打开屏幕的时间,而不是怀疑SLC事件已触发的时间。

我访问或地区都没有这个问题,只有SLC。顺便说一下,代码已经经历了许多更改,试图将其降低。最近的尝试(下面的代码)是将所有内容放入appDelegate中。

有任何想法吗?
预先感谢您的任何想法!

编辑:我添加了beginBackgroundTaskWithExpirationHandler,它也在我的原始测试中。

//  AppDelegate.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
  @property (strong, nonatomic) UIWindow *window;
  @property (strong, nonatomic) CLLocationManager *locationManager;
@end



//  AppDelegate.m

#import "AppDelegate.h"
#import "clsCommon.h"
@interface AppDelegate ()
@end
@implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Ask iOS for more time to process - before we do anything else
  [clsCommon sharedInstance].backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];

    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didFinishLaunchingWithOptions"];

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
      [self.locationManager setAllowsBackgroundLocationUpdates:YES];
    }
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.locationManager.distanceFilter = kCLDistanceFilterNone;
    self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    self.locationManager.allowsBackgroundLocationUpdates = YES;
    self.locationManager.pausesLocationUpdatesAutomatically = NO;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
      [self.locationManager requestAlwaysAuthorization];
    }

    [self.locationManager startMonitoringSignificantLocationChanges];

    return YES;
  }


  - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
    [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations"];
    CLLocation * currentLocation = [locations objectAtIndex:0];
    if(currentLocation !=nil) {
      [[clsCommon sharedInstance] sendBackgroundTestRecord:@"didUpdateLocations curLoc not nill"];
   }

 }

@end

最佳答案

好吧,知道iOS如何积极地解决所有折衷方案以延长电池寿命时,我不会感到非常惊讶。例如,“面包屑”应用程序的行为(在当前位置设置100m地理围栏,在退出事件时将该地理围栏移动到新位置)取决于iPhone是否一直在口袋里睡觉,还是偶尔检查锁定屏幕。

但是,昨天回家时运行与您的应用程序非常相似的应用程序确实为我生成了位置更新。

SLC读数之间的距离在4至14 km范围内,两次连续读数之间的最小时间间隔为14分钟。该应用程序与您的应用程序非常相似,它不包含任何联网部分,只是将事件记录到本地文件中(通过stderr重定向的NSLog)。另外,我不配置与位置管理器中的SLC不相关的属性,例如desiredAccuracy,distanceFIlter,activityType。我建议您从准系统应用程序开始,观察改进情况,以防出现问题。

要检查的一件事是您的应用在处理位置更新时是否崩溃。如果它在后台发生,除非您运行日志记录或通过Settings.app检查崩溃日志,否则您不会注意到这一点。

10-08 07:46