Могу ли я поместить цикл в dispatch_async, когда мое приложение переходит в фоновый режим?

Я хочу создать приложение для iOS. Идея состоит в том, чтобы запустить UILocalNotification, когда состояние вызова Connected. Я пытаюсь использовать dispatch_async блок в методе applicationDidEnterBackground и помещаю в этот блок цикл while(!isConnected), чтобы узнать, когда должен быть запущен UILocalNotificacion. Цикл проверяет состояние вызова и решает, когда запускать уведомление.

Что мне нужно знать, это правильный способ решить мою проблему? или у кого-нибудь есть идея получше?

Хорошо, это мой код:

- (void)applicationDidEnterBackground:(UIApplication *)application
 {

// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
isAlive = YES;

NSLog(@"BackgroundTimerRemaining %f", [application backgroundTimeRemaining]);

// verufy status of call
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
    // Clean up any unfinished task business by marking where you
    // stopped or ending the task outright.
    [application endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

[self readLocalVariableCalling];

__block int connected = 0;

__block int callingTemp = 1;//((NSNumber*)[self.datos objectForKey:@"calling"]).intValue;
NSLog(@"callingTemp: %d", callingTemp);

__strong typeof(self) weakSelf = self;

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    @autoreleasepool
    {
        //isAlive = YES;
        // Do the work associated with the task, preferably in chunks.
        while (callingTemp == 1)
        {
            if (callCenter != nil)
            {

            callCenter.callEventHandler = ^(CTCall* call)
            {
                NSLog(@"Loop - Call EventHandler state: %@", call.callState);
                if([call.callState isEqualToString:CTCallStateDisconnected])
                {

                    NSLog(@"disconnected");
                    [[UIApplication sharedApplication] cancelAllLocalNotifications];
                    callingTemp = 0;
                    connected = 0;
                    [weakSelf.datos setObject:[NSNumber numberWithInt:0] forKey:@"calling"];
                    [weakSelf saveLocalVariableCalling];

                }
                if ([call.callState isEqualToString:CTCallStateDialing] &&
                    connected == 0)
                {
                    NSLog(@"connected - Call EventHandler state : %@", call.callState);
                    connected = 1;
                    if (callingTemp == 1
                        && weakSelf.timerTableViewController.currentTimer)
                    {

                        TimeDto *currentTimer = weakSelf.timerTableViewController.currentTimer;
                        NSInteger seconds = currentTimer.value.intValue;

                        NSLog(@"minutos a segundos = %d", seconds);

                        NSDate *alertTime = [[NSDate date] dateByAddingTimeInterval:seconds];
                        UIApplication* app = [UIApplication sharedApplication];

                        if (weakSelf.notifyAlarm)
                        {
                            weakSelf.notifyAlarm.fireDate = alertTime;
                            weakSelf.notifyAlarm.timeZone = [NSTimeZone defaultTimeZone];
                            weakSelf.notifyAlarm.repeatInterval = 0;
                            weakSelf.notifyAlarm.soundName = @"road.caf";

                            NSString *messageTimer = NSLocalizedString(@"messageTimer", nil);
                            weakSelf.notifyAlarm.alertBody = [NSString stringWithFormat:messageTimer, ((int)currentTimer.value.intValue / 60 ) , (currentTimer.value.intValue % 60)];

                            [app scheduleLocalNotification:weakSelf.notifyAlarm];
                        }
                    }
                }


            };
            }
            else
            {
                NSLog(@"callCenter is null");
            }
            //NSLog(@"loop call state");

        }

        NSLog(@"Call Finished");


        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }

});
}

person kakashy    schedule 05.06.2013    source источник
comment
Мне действительно не нравится идея занятого ожидания. Проверьте stackoverflow.com/questions/3319805/   -  person Mohannad A. Hassan    schedule 06.06.2013
comment
Хорошо, но это в iOS 4, теперь у нас iOS 6, думаю, я мог бы быть возможным решением   -  person kakashy    schedule 06.06.2013
comment
На самом деле меня беспокоит, что while(!isConnected) потратит циклы вашего процессора.   -  person Mohannad A. Hassan    schedule 06.06.2013
comment
Может быть, вы правы, но я думаю, что while(!isConnected) не работает много времени, потому что цикл прерывается, когда состояние вызова Connected.   -  person kakashy    schedule 06.06.2013
comment
Почему отрицательный отскок в моем вопросе? Я должен иметь право спросить, потому что нет плохих вопросов :(   -  person kakashy    schedule 06.06.2013
comment
это едва ли реальный вопрос. дайте нам код, а не отдельные строчки.   -  person vikingosegundo    schedule 06.06.2013


Ответы (1)


Независимо от того, как вы планируете работу, когда ваше приложение работает в фоновом режиме, ему разрешается только определенная дальнейшая обработка, прежде чем все действия будут остановлены. Попытки dispatch_async волшебным образом не купят вам постоянную многозадачность.

Итак, нет, я не думаю, что это решит вашу проблему.

person Tommy    schedule 06.06.2013
comment
Хорошо, но я знаю, что dispatch_async есть тайм-аут (10 минут). Думаю, этого времени достаточно для моей цели, Вам не кажется? - person kakashy; 06.06.2013
comment
У него нет официально задокументированного тайм-аута. Вы можете использовать beginBackgroundTaskWithExpirationHandler, чтобы запросить некоторую фоновую обработку, но количество времени, которое вам будет разрешено, не задокументировано. Я думаю, что корень проблемы в том, что вы явно хотите делать то, чего Apple не хочет, чтобы вы делали. Это для магазина приложений? - person Tommy; 06.06.2013
comment
Недокументированное время составляет 2 минуты, я полагаю - person Sulthan; 27.11.2017