I am using background task to run the timer in the background to update the user\'s location. It\'s declared as:
UIBackgroundTaskIdentifier bgTask;
I lose many days looking for the piece of code or framework that was causing this warning in the debug console Can't end BackgroundTask: no background task exists with identifier 2 (0x2), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.
Finally I've created an empty project Single View App. Only code generated by Xcode, I run the app on simulator, put it in background and I see the same warning. So I can say it's an iOS 13 issue. I hope Apple will fix it quickly because in Crashlytics I found some crash in my app caused by it.
You need to set bgTask = UIBackgroundTaskInvalid
in two moments
I believe you are missing any of those two moments and that is why you are getting that error.
See apple example code:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task, preferably in chunks.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
link: https://developer.apple.com/documentation/backgroundtasks/bgtask?language=objc
Using Swift 5 - IOS 13.2.2 - Xcode 11.2 beta 2 (11B44) I managed to get rid of this error by
enabling Push notifications in the Capabilities of the app
Import the UserNotifications framework
then add this code to
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
// If granted comes true you can enabled features based on authorization.
guard granted else { return }
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
Are you using location update in the background?
If yes, add the below code at the time of getting location authorization from the user - Apple changed the default for allowsBackgroundLocationUpdates
to NO
from iOS 9 onwards.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
locationManager.allowsBackgroundLocationUpdates = YES;
}
Please make sure that you activated the 'Location updates' for background modes under your project 'Signing & Capabilities'. Otherwise it will crash.
I had the same issue and figured out the cause and solution!
Apple has fixed this issue in iOS 13.4 GM though I have workaround for the earlier versions.
While you should embrace using scenes when your app is run under iOS 13 and later, you can fully opt-out while you still support iOS 12 or earlier.
Application Scene Manifest
” entry from Info.plist.var window: UIWindow?
to your app delegate.Happy coding!
Reproduced, here is my entire app:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
return true
}
}
And when I take it to background I get the same message. No storyboard or any other noise.