2013-03-14 7 views
3

Мне нужна долгая задача, выполняемая как в фоновом режиме, так и на переднем плане. Это обновляет основные данные. Поэтому, чтобы поддерживать пользовательский интерфейс, я создал другой поток, в котором я использую другой 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]; 
} 

ответ

17

Причина, по которой applicationDidEnterBackground: и applicationDidEnterForeground: никогда не называются, является потому что эти методы используются в сочетании с Application does not run in background, этот параметр можно найти в вашем ***-info.plist. Если этот параметр установлен на YES, то ваше приложение никогда не вызовет эти методы, потому что при нажатии кнопки «домой» с приложением, которое установило параметр YES, экземпляр приложения, которое запущено, будет прекращено, поэтому каждый раз, когда вы нажимаете кнопку home, а затем выберите значок приложения, в котором создается новый экземпляр, поэтому он использует applicationWillTerminate:.

Методы, которые Kirti mali сказал бы также неправильные методы использовать для хотим, чтобы вы после этого, по причине того, что applicationDidBecomeActive: и applicationWillResignActive: используются, когда что-то нравится, когда вы отвечаете на телефонный звонок. Выполнение экземпляра не прекращается и не отправляется в фоновый режим. Экземпляр приостанавливается до тех пор, пока пользователь не закончит этот вызов, когда он снова станет активным.

Таким образом, решение, чтобы это было бы, если вы хотите, чтобы приложение, чтобы работать в фоновом режиме будет изменить параметр «Application does not run in background» в ***-info.plist to be NO justapplicationDidBecomeActive:andapplicationWillResignActive: `неправильный путь для этих методов, которые будут использоваться.

Чтобы получить лучшее представление об этих методах, см. Документацию на ящик UIApplicationDelegate.

+0

Большое спасибо. Теперь я могу понять. Это было очень полезно. На самом деле я хочу вызвать таймер только тогда, когда он находится в фоновом режиме. И это приложение использует службу определения местоположения и, таким образом, «Приложение не работает в фоновом режиме» в info.plist установлено в «YES». Есть ли способ узнать, входит ли он в фон? – aparna

+0

Поместите некоторые «NSLogs» для запуска в «NSTimers», но вы узнаете, отправлено ли оно на фон, потому что, как только вы вернетесь в приложение, исполняемый экземпляр приложения будет продолжен. – Popeye

+0

Просто убедитесь, что вы установили «Приложение не работает в фоновом режиме» в НЕТ, и оно будет работать в фоновом режиме. – Popeye

0

Этот метод вызывается при нажатии кнопки домой нажата

- (void)applicationDidBecomeActive:(UIApplication *)application 

и этот метод вызывается, когда значок кнопки нажата

- (void)applicationWillResignActive:(UIApplication *)application 
+0

За этим следуют эти два метода? – aparna

+0

Я упомянул несколько сайтов, в которых объяснялось, что эти методы будут вызваны, а затем приложение application (application): (void) applicationDidBecomeActive: (UIApplication *) и - (void) applicationWillResignActive: (UIApplication *) http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/и https://s3-ap-northeast-1.amazonaws.com/booksikindle/html/Beginning%20IOS%205%20Development1/Beginning_iO-ng_the_iOS_SDK_split_039. HTML. – aparna

+0

да, это хорошо работает –