O que acontece com um aplicativo do iPhone quando o iPhone entra em modo de espera?

Meu aplicativo usa o NSTimer e parece que o NSTimer não triggers quando o iPhone entra no modo de espera (pressionando o botão de hardware ou o timer de inatividade).

Quando eu ativo o iPhone novamente, meu aplicativo ainda está em primeiro plano. O que acontece com aplicativos de terceiros quando o iPhone é o modo de espera?

Embora não seja evidente aqui, acredito que o pôster original encontrou uma resposta para sua pergunta, iniciando um tópico ( disponível aqui ) nos Fóruns de Desenvolvedores do iPhone (que eventualmente tive de encontrar porque as informações não eram compartilhadas aqui).

No caso de alguém ter a mesma pergunta e encontrar a página no futuro, aqui está uma resposta útil que foi postada por alguém no fórum da Apple chamado “eskimo1” (que eu editei levemente para facilitar a leitura sem ter o contexto fornecida por todo o segmento original):

  • Quanto à terminologia de status do aplicativo para iPhone, “ativo” não significa “acordado”, significa “anexado à GUI”. Pense nisso como sendo análogo ao “mais à frente” no Mac OS X. Quando você bloqueia o dispositivo, seu aplicativo é desativado, mas o dispositivo pode ou não adormecer
  • O iPhone OS raramente dorme se o dispositivo estiver conectado à energia principal (ou seja, via USB). Pode dormir se estiver funcionando com bateria, no entanto.
  • Pouco tempo depois que a canvas é bloqueada (20 segundos, de acordo com Oliver Drobnik), o dispositivo dorme. Isto é como fechar a tampa do seu laptop; toda a atividade na CPU principal é interrompida.
  • Isso não acontece se o dispositivo estiver reproduzindo áudio na session de áudio correta. Veja DTS Q & A QA1626 “Sessão de Áudio – Garantir que a reprodução de áudio continue quando a canvas estiver bloqueada” para detalhes.
  • Observe que a propriedade idleTimerDisabled (que pode ser ativada para evitar que a canvas seja desativada enquanto o aplicativo está em execução) é para bloquear a canvas após a inatividade do usuário. Não está diretamente relacionado ao sono do sistema (está indiretamente relacionado em que o sistema pode dormir logo após ser bloqueado).

Consulte Interrupções do aplicativo no Guia de programação do sistema operacional do iPhone , especialmente os events applicationDidBecomeActive e applicationDidBecomeActive . (Todo o guia vale a pena ser lido.) Quando você ignora os events, o cronômetro parece continuar por algum tempo e depois pára. Parece lógico, o aplicativo poderia facilmente drenar a bateria se mantido em execução. E o que exatamente acontece com o aplicativo? Eu acho que simplesmente não tem tempo de CPU – ele congela e só derrete quando você liga a máquina “de volta”.

Meu primeiro conselho é não desativar o timer inativo, que é apenas um hack. Se você quiser manter um timer ativo durante os events de interface do usuário, execute o cronômetro no loop de execução atual usando NSCommonModes:

 // create timer and add it to the current run loop using common modes self.timer = [NSTimer timerWithTimeInterval:.1 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; 

Eu usei as informações deste post para uma pequena amostra que eu estava construindo. Este é o código que usei quando iniciei a reprodução para impedir que o áudio parasse:

 AudioSession.Category = AudioSessionCategory.MediaPlayback; 

E quando o aplicativo é feito com a reprodução para redefinir para o valor original:

 AudioSession.Category = AudioSessionCategory.SoloAmbientSound; 

A amostra completa está aqui:

http://github.com/migueldeicaza/monotouch-samples/tree/master/StreamingAudio/

Fui confrontado com esse problema recentemente em um aplicativo em que estou trabalhando, que usa vários timers e reproduz alguns prompts de áudio e fez duas alterações relativamente simples:

  1. No AppDelegate eu implementei os seguintes methods e a mera presença permite que o aplicativo continue quando a canvas está bloqueada

     // this receives the notification when the device is locked - (void)applicationWillResignActive:(UIApplication *)application { } // this receives the notification that the application is about to become active again - (void)applicationWillBecomeActive:(NSNotification *)aNotification { } 

    Referências: Referência de Protocolo UIApplicationDelegate & Referência de Classe NSApplication no documento API (acessível via Xcode, apenas procure por applicationWillBecomeActive ).

  2. Fez a class viewcontroller principal um AVAudioPlayerDelegate e usou esse código da amostra “AddMusic” da Apple para fazer os alertas de áudio que o app tocou bem no iPod, etc …

    Acabei de soltar esse código em um método chamado durante viewDidLoad. Se isso lhe interessa, você se enquadra na categoria “quem deve ler este documento” para isso: Guia de Programação de Sessão de Áudio

     // Registers this class as the delegate of the audio session. [[AVAudioSession sharedInstance] setDelegate: self]; // The AmbientSound category allows application audio to mix with Media Player // audio. The category also indicates that application audio should stop playing // if the Ring/Siilent switch is set to "silent" or the screen locks. [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil]; // Activates the audio session. NSError *activationError = nil; [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 

Eu acredito que seu aplicativo deve ser executado normalmente quando suspenso. (pense no Pandora Radio)

Verifique se o cronômetro está sendo desalocado devido à ocultação de sua visualização ou a ocorrência de algum outro evento.