我想检查应用程序是否在后台运行.
在:
locationManagerDidUpdateLocation {
if(app is runing in background){
do this
}
}
Run Code Online (Sandbox Code Playgroud) objective-c uiapplicationdelegate application-lifecycle ios ios-background-mode
我正在编写一个需要高精度和低频率的背景位置更新的应用程序.该解决方案似乎是一个后台NSTimer任务,它启动位置管理器的更新,然后立即关闭.之前已经问过这个问题:
但我还没有得到最起码的例子.在尝试了上述接受的答案的每一个排列后,我总结了一个起点.输入背景:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"ending background task");
[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
self.timer = [NSTimer scheduledTimerWithTimeInterval:60
target:self.locationManager
selector:@selector(startUpdatingLocation)
userInfo:nil
repeats:YES];
}
Run Code Online (Sandbox Code Playgroud)
和委托方法:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"%@", newLocation);
NSLog(@"background time: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
[self.locationManager stopUpdatingLocation];
}
Run Code Online (Sandbox Code Playgroud)
当前行为是backgroundTimeRemaining
从180秒减少到零(记录位置时),然后执行到期处理程序,不再生成进一步的位置更新.如何修改上述代码以便在后台无限期地接收定期位置更新?
更新:我的目标是iOS 7,似乎有一些证据表明后台任务的行为有所不同:
objective-c core-location ios background-task ios-background-mode
我最近升级了我的iOS设备以使用iOS 7.我们正在开发的其中一个应用程序使用后台位置服务来跟踪设备位置,我们所有的测试人员都报告该应用程序不再出现在iOS下的后台跟踪7.
我们已经确认在设备上的设置中启用了应用程序的后台处理,并且之前的版本在iOS 6下运行良好.即使设备已循环,应用程序也会在位置更新后重新启动.
还有什么需要做才能在iOS 7下完成这项工作吗?
从iOS 12开始,CLLocationManager不再在后台运行.应用程序在随机时间没有崩溃日志的情况下终止.这在iOS 12之前运行良好.
为了演示这个问题,我在这里创建了一个示例应用程序
演示应用程序只是启动CLLocationManager并在后台运行它.在后台运行时,我们通过记录它来跟踪它.问题是应用程序被iOS终止.创建演示应用程序以演示此问题.
重现步骤
结果:
随机时间后应用程序无任何理由终止.
预期结果:
它应该如何工作
这是Apple工程师证实的:
一旦CLLocationManager更新在前台启动并且您完成了让它在后台运行的所有工作,位置更新应该在后台运行,直到:
我已经使用的应用程序WkWebView到从SoundCloud播放音频,iOS上的13测试版6音频停止时,应用程序是不是在前台,即使音频是在背景模式。
开始播放时,将抛出以下断言:
Error acquiring assertion: <NSError: 0x282cf67c0; domain: RBSAssertionErrorDomain; code: 2; reason: "Required client entitlement is missing"> {
userInfo = {
RBSAssertionAttribute = <RBSLegacyAttribute: 0x1592432e0; requestedReason: MediaPlayback; reason: MediaPlayback; flags: PreventTaskSuspend | PreventTaskThrottleDown | WantsForegroundResourcePriority>;
}
Run Code Online (Sandbox Code Playgroud)
进入后台状态后,将引发以下声明并暂停音频:
Can't end BackgroundTask: no background task exists with identifier 13 (0xd), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.
[ProcessSuspension] Background task expired while holding WebKit ProcessAssertion (isMainThread? 1).
Run Code Online (Sandbox Code Playgroud)
这在iOS 12中不会发生,在iOS 12中,音频在后台正常播放。
问题: 我想在应用程序进入后台 5 秒后运行一个简单的函数。
我必须实现BGTaskScheduler,以支持 iOS 13。 BackgroundTask 的旧实现适用于旧 iOS 版本。
我按要求添加了后台模式(勾选了 BLE 配件,因为我们在此功能中执行了一个小的 BLE 操作):
然后,我根据文档准备了 Info.plist(标识符是假的,仅用于 StackOverflow 问题):
在didFinishLaunchingWithOptions结束之前,我注册了我的 BackgroundTask:
if #available(iOS 13.0, *) {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.MyID", using: .global()) { (task) in
print("My backgroundTask is executed NOW!")
task.expirationHandler = {
task.setTaskCompleted(success: true)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当应用程序运行didEnterBackground方法时,我提交了一个 BackgroundTaskRequest:
if #available(iOS 13.0, *) {
do {
let request = BGAppRefreshTaskRequest(identifier: "com.example.MyID")
request.earliestBeginDate = Calendar.current.date(byAdding: .second, value: 5, to: Date())
try BGTaskScheduler.shared.submit(request)
print("Submitted …
Run Code Online (Sandbox Code Playgroud) 我试图了解 iOS 13 中后台工作的细节。
如果用户一周没有进入应用程序,BGProcessingTask 是否会完成,或者如果一周过去了,它将永远不会完成?
Apple 表示 BGProcessingTask 将能够运行几分钟 - 我们在谈论多少分钟?
Apple 文档还没有回答这些问题。答案可以通过实验获得,但我没有尝试过一周不使用该应用程序进行背景调查。
当在详细信息屏幕中的我的 iOS 应用程序中时,我按下主页按钮,这将导致它进入后台模式。在大约 7 分钟不活动后,我重新启动它,它不会从我离开它的地方开始。它从第一个屏幕开始。
我上网,开始了解国家保护和恢复。我在一个屏幕中实现,但它似乎不起作用。这就是我在 appDelegate.m 中所做的
//appDelegate.m
-(BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
return YES;
}
-(BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
return YES;
}
Run Code Online (Sandbox Code Playgroud)
以下代码位于 appDelegate.m 中的 willFinishLaunchingWithOptions 方法中。我没有使用故事板,因为这个应用程序很旧。它有 XIB。所以这个应用程序总是需要转到登录屏幕,在那里检查是否存储了 accessToken,它将从登录屏幕转到主屏幕。如果未存储,它将保留在登录屏幕中。所以这是必须执行的。因此,只有一种方法可以像下面这样编码。
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
...
loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc]initWithRootViewController:loginViewController];
self.navigationController.restorationIdentifier = @"NavigationController";
[loginViewController.view setBackgroundColor:[UIColor whiteColor]];
self.window.rootViewController = self.navigationController;
...
...
}
Run Code Online (Sandbox Code Playgroud)
我已经在 viewDidLoad() 中为所有视图控制器提供了恢复 ID,如下所示。例如这是我在 PetDetailViewController.m 中所做的
- (void)viewDidLoad
{
[super viewDidLoad];
self.restorationIdentifier = @"MatchedPetIdentification";
self.restorationClass = [self class]; …
Run Code Online (Sandbox Code Playgroud) application-restart ios uikit-state-preservation state-restoration ios-background-mode
我正在开发一个iOS(7.0+)应用程序,用于健身(运行),使用用户GPS位置,进行小规模计算并将数据传输到蓝牙低功耗(4.0)手表.此过程需要在后台进行,即使用户锁定其iOS设备也是如此.
我也实现了以下背景模式:
App communicates using CoreBluetooth
App registers for location updates
Run Code Online (Sandbox Code Playgroud)
我已经成功地使一切运行良好,除了在设备被锁定一段时间(例如2小时)后,iOS设备停止更新位置,因为我可以看到它不再发送更新GPS值到蓝牙手表.然后,我必须解锁设备,重新打开应用程序和位置服务,因为它应该再次工作.
有没有人知道如何让位置服务在后台运行(设备已锁定),而不会在一定时间后突然停止位置更新?如果可能的话,一个有效的解决方案是优选的,不会比正常情况下使用GPS消耗太多电池.
objective-c core-location cllocationmanager ios ios-background-mode