答案 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;或者如果它被注册为能够处理某种类型的内容。
如果应用程序在本地/远程通知触发时位于前台,则应用程序会直接接收该应用程序。
如果本地/远程通知触发时应用程序当前不在前台,则应用程序不会收到它。通知触发时没有执行代码!
只有当用户选择通知时,应用才会变为活动且可以执行。
请注意,用户可以针对整个设备或仅针对特定应用程序禁用通知,在这种情况下,用户将永远不会看到通知。如果在通知发生时关闭设备,则会丢失。
1)有一些新的后台模式,例如后台获取(但是你仍然不能以确定的方式被OS唤醒)
2)现在有一个后台推送通知
3)beginBackgroundTaskWithExpirationHandler时间从10分钟减少到3分左右。
答案 1 :(得分:2)
现在改变了 iOS7 ,现在是测试版。
采用新功能,使您的应用内容保持最新 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)
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()