iOS:让应用程序像服务一样运行

时间:2012-06-15 03:02:51

标签: ios iphone ipad foreground background-service

在iOS中,即使不再位于前台,我如何指示操作系统保持我的应用程序运行?

还有更多应用程序可以做到这一点。

4 个答案:

答案 0 :(得分:45)

基本上,iOS中没有服务类型应用或功能。 甚至“背景”应用程序(UIBackgroundMode)也无法完全免费运行,并且没有像其他操作系统上的服务或守护进程等限制。

这是关于后台执行和通知以及计时器等的情况。

1)应用程序无法在后台执行,除非:

a)它要求OS提供额外的时间。这是使用beginBackgroundTaskWithExpirationHandler完成的。 Apple没有明确(有意)指出这个额外时间有多长,但实际上大约需要10分钟。

b)应用程序具有后台模式,模式是VoIP,音频,位置,报亭。即使它有这些类型之一,应用程序也无法无限制地执行。本讨论的其余部分假定应用程序没有后台模式。如果您尝试使用其中一种后台模式使您的应用能够在后台运行,但您的应用无法合法使用特定功能,那么您的应用将在应用商店提交时被拒绝(即拥有UIBackgroundMode它必须是:一个VoIP应用程序,需要持续不断的位置更新,在后台连续播放音频的能力是一个基本功能,或者是报亭应用程序。)

2)当一个应用程序被暂停时,它无法做任何事情直接引发自己。它以前不能安排NSTimer,它不能使用像performSelector:afterDelay这样的东西。等

应用程序再次变为活动状态的唯一方式是,如果USER执行某些操作以使其处于活动状态。用户可以通过以下方式执行此操作:

a)直接从其图标

启动应用程序

b)启动应用以响应应用在其处于活动状态时之前安排的本地通知。

c)启动应用程序以响应服务器发送的远程通知。

d)其他一些:例如,如果应用程序已注册处理通过URL启动,则启动URL;或者如果它被注册为能够处理某种类型的内容。

如果应用程序在本地/远程通知触发时位于前台,则应用程序会直接接收该应用程序。

如果本地/远程通知触发时应用程序当前不在前台,则应用程序不会收到它。通知触发时没有执行代码!

只有当用户选择通知时,应用才会变为活动且可以执行。

请注意,用户可以针对整个设备或仅针对特定应用程序禁用通知,在这种情况下,用户将永远不会看到通知。如果在通知发生时关闭设备,则会丢失。

IOS 7的更新

1)有一些新的后台模式,例如后台获取(但是你仍然不能以确定的方式被OS唤醒)

2)现在有一个后台推送通知

3)beginBackgroundTaskWithExpirationHandler时间从10分钟减少到3分左右。

答案 1 :(得分:2)

现在改变了 iOS7 现在是测试版

来自Apple's developer portal

  

采用新功能,使您的应用内容保持最新   iOS 7中的多任务API。新服务允许您的应用更新   信息并在后台下载内容而不会耗尽   不必要的电池。更新可能发生在机会主义   时间,并根据使用情况智能安排,所以你的应用程序   可以在用户需要时更新后台内容。

答案 2 :(得分:0)

是的,我们可以做到这一点,

创建私人字段以跟踪我们的状态:

UIBackgroundTaskIdentifier _bgTask;

现在调用此方法,像服务一样运行您的应用

if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) 
{
   _bgTask = UIBackgroundTaskInvalid;
   [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doBackground:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
}

现在创建一个选择器 -

- (void) doBackground:(NSNotification *)aNotification
{
   UIApplication *app = [UIApplication sharedApplication];

   if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
   {
      _bgTask = [app beginBackgroundTaskWithExpirationHandler:^
      {
         dispatch_async(dispatch_get_main_queue(), ^
         {
            if (_bgTask != UIBackgroundTaskInvalid)
            {
               [app endBackgroundTask:_bgTask];
               _bgTask = UIBackgroundTaskInvalid;
            }
         });
      }];
   }
}

完成任务后,请拨打以下代码 -

UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(endBackgroundTask:)]) 
{
   if (_bgTask != UIBackgroundTaskInvalid)
   {
      [app endBackgroundTask:_bgTask];
      _bgTask = UIBackgroundTaskInvalid;
   }
}

答案 3 :(得分:0)

@Zoeb S答案的

Swift 版本。也许不是OP的正确答案。但这将有助于您在应用程序进入后台时启动background task。并在一段时间后被iOS杀死(希望在处理完成后)。

声明变量

fileprivate let backgroundTaskStarter = {
  // TODO: If this doesn't work, switch to willResignActiveNotification.
  UIApplication.didEnterBackgroundNotification.observe() { _ in
    UIApplication.shared.beginBackgroundTask {
      NSLog("endBackgroundTask called by iOS")
    }
  }
}()

Filename.swift的{​​{1}}方法中,执行以下操作:

init()