首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用程序在ios7中被操作系统在几秒钟后被-edit杀死

应用程序在ios7中被操作系统在几秒钟后被-edit杀死
EN

Stack Overflow用户
提问于 2014-02-07 11:13:13
回答 3查看 2.2K关注 0票数 3

我正在为iOS 7创建基于导航的应用程序,我使用CoreLocation框架获取用户的位置数据,

应用程序的要求是在特定的时间开始获取用户的位置,因为我已经用didReceiveRemoteNotification fetchCompletionHandler:方法实现了沉默的推送通知,

,我已经成功地实现了,使用&它调用startUpdatingLocation,并且我能够在委托方法中获得位置数据:

使用此有效载荷:

{"aps" : {"content-available" : 1},"SilentPush" : "4"}

我为后台模式启用了location & remote notification

代码语言:javascript
复制
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
     __block UIBackgroundTaskIdentifier bgTask =0;
    UIApplication  *app = [UIApplication sharedApplication];
     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [self.locationManager startUpdatingLocation];

 }];

didUpdateLocations

代码语言:javascript
复制
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
        lastLoc=[locations lastObject];
        [logFile addLocObject:[NSString stringWithFormat:@"Loc: %@",lastLoc]];
}

但是问题是:

几秒钟后,location类的委托方法停止,如果设备移动,它将不会发送任何数据,当我将app与前台对话时,它将被称为'didFinishLaunhing‘方法,因此我猜os会在更新位置时杀死应用程序,在设备Diagnostics & usage中,我将得到以下崩溃报告:

代码语言:javascript
复制
Application Specific Information:
MockUpApp2[390] has active assertions beyond permitted time: 
{(
    <BKProcessAssertion: 0x145ac790> identifier: Called by MockUpApp2, from -[AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler:] process: MockUpApp2[390] permittedBackgroundDuration: 40.000000 reason: finishTaskAfterBackgroundContentFetching owner pid:390 preventSuspend  preventIdleSleep  preventSuspendOnSleep 
)}

昨天我问了这个问题,现在我可以通过推送通知启动后台位置管理器了,

所以请任何人都能解决这个问题。

谢谢。

注意:如果我在调试模式下运行应用程序,意味着我通过XCode运行应用程序&不停止或不断开连接,应用程序将运行。在这种情况下,应用程序不会被OS停止。

编辑1

如@Stephen所述,如果我删除所有背景文件,

代码语言:javascript
复制
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
        [self.locationManager startUpdatingLocation];

}

现在应用程序连一次都不会调用didUpdateLocations

我应该用这种方法写些什么?

Edit 2

根据苹果博士的说法:

If your app is suspended or not running, the system wakes up or launches your app and puts it into the background running state before calling the method.

那么,如果我启用了位置后台模式,应用程序应该在后台运行吗?

EN

回答 3

Stack Overflow用户

发布于 2014-02-07 11:58:26

我认为iOS上的后台处理不像您所期望的那样有效。这不像在Mac或Windows上那样,您可以在后台无限期地运行(即使是在iOS 7中的更改)。

所以,要直接回答你的问题:你开始了一项可以继续在后台运行的任务。有两个“但是”

  1. 代码块是过期处理程序。不是要在后台运行的代码。这段代码将在后台任务过期之前执行(因此,在您的应用程序被杀死之前,它很快就会执行)。苹果并没有真正记录这是多长时间,但看起来你似乎得到了大约40秒。要在后台运行的代码是beginBackgroundTaskWithExpirationHandler之后的行。当你完成的时候,你说endBackgroundTask:
  2. 其次,位置更新在没有所有beginBackgroundTaskWithExpirationHandler:内容的背景下工作。即使应用程序在后台,委托方法也会被调用。

总结:删除beginBackgroundTaskWithExpirationHandler:语句。您只需添加startUpdatingLocation:即可。

票数 3
EN

Stack Overflow用户

发布于 2014-02-07 11:54:47

不久前,我使用CLLocation做了很多工作,我有一些评论和建议,但可能没有完整的解决方案。

我看到您正在将您的反应放在beginBackgroundTaskWithExpirationHandler块中的无声通知上。我认为这是不对的。不过,我确实认为您应该在backgroundTask方法上使用该CLLocationDelegate模式。

更重要的是,苹果很有可能会拒绝你在后台进程中使用位置标志。从我的经验中。我花了很多时间研究如何合理地使用定位服务,提高了我自己流程的准确性。我甚至启用了许多防止过度使用电池的保护措施,他们未经讨论就拒绝了它。我做了,所以它只使用后台服务时,设备是插入充电器。我提出了上诉,并为负责任的使用提出了一个很好的理由,但没有结果。

您应该查找这些术语,并确保您的用例按照声明准确地包含在其中,否则它不会浮出水面。

我仍然说,没有背景服务,你就能得到你想要的东西。使用重要的位置更改和区域监视,您的应用程序将不需要任何东西,但保存最新的已知位置和响应通知。

我会想到这样的方案:

  • 重要的位置更改事件出现了。检查速度/活动。您可以在不启用后台服务的情况下执行此操作。
  • 如果开车只需保存位置。你在开车时会经常换车,所以你只会落后几分钟。
  • 不驱动或闲置,创建一个区域的合理大小取决于您的准确性要求。只要设备位于该区域,就可以使用当前保存的最近位置。这将是在24小时内的大部分时间,所以你是影响电池非常少的整体。

在我看来,你是从错误的角度看待这件事的。这是合乎逻辑的,认为你会发送信息,然后作出回应,让CL做些什么。这不是服务的目的。基本上,您设置了位置管理器,并让它离开。

查看我在GitHub上的存储库中使用的一些模式可能会使您受益。

TTLocationHandler

它已经一年没有更新了,我也不记得我在工作中学到了什么,但是它为我提供了坚实的服务,因为我没有必要去摆弄它。

按照该示例,您将停止并启动,或切换到或从区域或重要位置更改监视所有基于应用程序状态。不需要互动。

您的位置事件是处理的,因为他们来,背景或否。

在您的远程通知响应中,您只会阅读最新的位置信息或任何您需要的信息,并按照您的意图行事。这里不打电话给startUpdatingLocation。如果您在后台使用位置服务,您就不应该首先停止它。

编辑-正确使用Expiration块

代码语言:javascript
复制
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    __block UIBackgroundTaskIdentifier bgTask =0;
    UIApplication  *app = [UIApplication sharedApplication];
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
          // Do something here. Perhaps you'll log the error or respond with some fall back
          // This block will only be run if the handler expires without having been ended
          // In that case, you need to end it now or you will crash
          If (bgTask != UIBackgroundTaskInvalid) {
              [app endBackgroundTask:bgTask];
              [bgTask = UIBackgroundTaskInvalid];
          }

      }];

      // This is where the code you intend to run in the background starts

     [self.locationManager startUpdatingLocation];

     // Now tell the system you are finished, ending background task normally before exit

     If (bgTask != UIBackgroundTaskInvalid) {
         [app endBackgroundTask:bgTask];
         [bgTask = UIBackgroundTaskInvalid;
     }
}
票数 2
EN

Stack Overflow用户

发布于 2014-02-07 11:53:42

方法beginBackgroundTaskWithExpirationHandler:给它的应用程序时间,但这并不意味着任务可以永远运行。

正如崩溃日志中所述,你的应用程序被杀死了,因为你的时间显然快用完了。

您应该得到相同的结果,只要求位置更新,而不包装到过期处理程序。

我记得,在旧系统中,我通过使用区域监视触发背景中的位置更新来管理类似的事情。

编辑

为了有最好的结果,同时玩的位置,我建议你使用真正的设备,也许你是。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21626286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档