Мне нужна долгая задача, выполняемая как в фоновом режиме, так и на переднем плане. Это обновляет основные данные. Поэтому, чтобы поддерживать пользовательский интерфейс, я создал другой поток, в котором я использую другой managedObjectContext (MOC). Таким образом, таймер установлен как в фоновом режиме, так и на переднем плане и поэтому инактивируется при изменении состояния. Перед запуском задачи и после завершения задачи, когда я нажимаю кнопку «домой», она правильно вызывает два метода делегирования, но во время выполнения задачи активна, когда я нажимаю изменения экрана на домашней кнопке, и пользовательский интерфейс зависает (становится пустым), но эти два метода делегирования не являются и приложение не прекращается. Я не мог найти причину, по которой это происходит. Было бы полезно, если кто-то может помочь.applicationDidEnterBackground и applicationWillEnterForeground метод не вызывается, когда нажата кнопка home в iOS-симуляторе
Я приложу необходимый код с этим:
-(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];
}
Большое спасибо. Теперь я могу понять. Это было очень полезно. На самом деле я хочу вызвать таймер только тогда, когда он находится в фоновом режиме. И это приложение использует службу определения местоположения и, таким образом, «Приложение не работает в фоновом режиме» в info.plist установлено в «YES». Есть ли способ узнать, входит ли он в фон? – aparna
Поместите некоторые «NSLogs» для запуска в «NSTimers», но вы узнаете, отправлено ли оно на фон, потому что, как только вы вернетесь в приложение, исполняемый экземпляр приложения будет продолжен. – Popeye
Просто убедитесь, что вы установили «Приложение не работает в фоновом режиме» в НЕТ, и оно будет работать в фоновом режиме. – Popeye