Метод applicationDidEnterBackground и applicationWillEnterForeground не вызываются при нажатии кнопки "Домой" в симуляторе iOS
Мне нужно долгое задание, которое нужно выполнить как в фоновом режиме, так и на переднем плане. Это обновляет основные данные. Поэтому, чтобы поддерживать отзывчивость пользовательского интерфейса, я создал еще один поток, в котором я использую другой managedObjectContext(MOC). Поэтому таймер устанавливается как в фоновом режиме, так и на переднем плане и соответствующим образом деактивируется при изменении состояния. Перед запуском задачи и после ее завершения, когда я нажимаю кнопку "Домой", она правильно вызывает два метода делегата, но во время выполнения задачи она активна, когда я нажимаю кнопку "Домой", меняется экран, и пользовательский интерфейс зависает (становится пустым), но два метода делегата не отображаются. называется правильно, и приложение не прекращается. Я не мог найти причину, почему это происходит так. Было бы полезно, если кто-то может помочь.
Я приложу необходимый код с этим:
-(void) startTimerThread
{
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Add code here to do background processing
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator]];
self.managedObjectContext = context;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:context];
NSLog(@"managedObjContext : %@\n",self.managedObjectContext);
[self getDataFromFile];
dispatch_async( dispatch_get_main_queue(), ^{
// Add code here to update the UI/send notifications based on the
// results of the background processing
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAppDelegateTable" object:nil];
[context release];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:context];
});
});
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"Background\n");
[self.notificationTimer invalidate];
self.notificationTimer = nil;
UIApplication *app = [UIApplication sharedApplication];
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//start location update timer and background timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:180 target:self
selector:@selector(startLocationServices) userInfo:nil repeats:YES];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
self.logDownloader.managedObjectContext = self.managedObjectContext;
NSLog(@"managedObjContext : %@\n",self.logDownloader.managedObjectContext);
self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:90 target:self.logDownloader selector:@selector(getDataFromFile) userInfo:nil repeats:YES];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"Foreground\n");
//invalidate background timer and location update timer
[self.timer invalidate];
[self.backgroundTimer invalidate];
self.timer = nil;
self.notificationTimer = nil;
self.logDownloader.managedObjectContext = self.managedObjectContext;
NSLog(@"managedObjContext : %@\n",self.logDownloader.managedObjectContext);
[[NSNotificationCenter defaultCenter] postNotificationName:@"ReloadAppDelegateTable" object:nil];
self.notificationTimer = [NSTimer scheduledTimerWithTimeInterval:180 target:self.logDownloader selector:@selector(startTimerThread) userInfo:nil repeats:YES];
}
2 ответа
Причина по которой applicationDidEnterBackground:
а также applicationDidEnterForeground:
никогда не называются, потому что эти методы используются в сочетании с Application does not run in background
эта опция может быть найдена в вашем ***-info.plist
, Если эта опция установлена YES
чем ваше приложение никогда не будет вызывать эти методы, потому что они, когда вы нажимаете кнопку домой с приложением, которое установило опцию YES
экземпляр запущенного приложения будет прерван, поэтому каждый раз, когда вы нажимаете кнопку "Домой" и затем выбираете значок приложения, создается новый экземпляр, поэтому он использует applicationWillTerminate:
,
Методы, которые Kirti mali
сказал, что также будут неправильные методы, которые вы хотите использовать, потому что причина в том, что applicationDidBecomeActive:
а также applicationWillResignActive:
используются, когда что-то вроде, когда вы отвечаете на телефонный звонок. Запуск экземпляра не прекращается и не отправляется в фоновый режим. Экземпляр приостанавливается до тех пор, пока пользователь не завершит этот вызов, когда он снова станет активным.
Таким образом, решение этого было бы, если вы хотите, чтобы приложение запускалось в фоновом режиме, было бы изменить параметр " Application does not run in background
" в ***-info.plist to be
НЕТ just
applicationDidBecomeActive: and
applicationWillResignActive: `неправильный способ использования этих методов.
Пожалуйста, смотрите документацию Apple на UIApplicationDelegate
чтобы лучше понять эти методы.
В iOS13+, если вы реализуете UIWindowSceneDelegate, он вызывает func sceneDidEnterBackground(_ scene: UIScene)
вместо этого.
Поскольку ваше приложение работает в фоновом режиме, эти методы никогда не будут вызываться, однако вы можете использовать willEnterForegroundNotification и didEnterBackgroundNotification, чтобы делать то же самое, что и вы.
Вы можете написать следующие коды внутри метода didFinishLaunchingWithOptions ApplicationDelegate
NotificationCenter.default.addObserver(forName:UIApplication.willEnterForegroundNotification, object: nil, queue: nil) { (_) in
// Your Code here
}
NotificationCenter.default.addObserver(forName:UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { (_) in
// Your Code here
}
Этот метод вызывается при нажатии кнопки домой
- (void)applicationDidBecomeActive:(UIApplication *)application
и этот метод вызывается при нажатии кнопки со значком
- (void)applicationWillResignActive:(UIApplication *)application