O iOS iniciará meu aplicativo em segundo plano se ele for forçado a sair pelo usuário?

219

Estou acionando uma busca em segundo plano usando o content-availablesinalizador em uma notificação por push. Eu tenho o fetche remote-notification UIBackgroundModesativado.

Aqui está a implementação que estou usando no meu AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification Recieved");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody =  @"Looks like i got a notification - fetch thingy";
    [application presentLocalNotificationNow:notification];
    completionHandler(UIBackgroundFetchResultNewData);

}

Quando o aplicativo está sendo executado em segundo plano, ele funciona bem. (A notificação é recebida e o aplicativo acionou a notificação local "parece que recebi uma notificação", como o código acima deve fazer).

No entanto, quando o aplicativo não está em execução e uma notificação por push é recebida com o content-availablesinalizador, o aplicativo não é iniciado e o didRecieveRemoteNotificationmétodo delegado nunca é chamado.

O vídeo da WWDC O que há de novo na multitarefa (nº 204 da WWDC 2013) mostra isso:insira a descrição da imagem aqui

Ele diz que o aplicativo é "iniciado em segundo plano" quando uma notificação por push é recebida com o content-availablesinalizador.

Por que meu aplicativo não está sendo iniciado em segundo plano?

Portanto, a verdadeira questão é:

O iOS executará tarefas em segundo plano depois que o usuário forçar o encerramento do aplicativo?

Papai Noel
fonte
Como você está verificando se o aplicativo é iniciado em segundo plano?
runmad
1
@runmad Eu registro um monte de porcaria em #- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Papai Noel
Como você está registrando, apenas o NSLog? Você vai ter que definir o lançamento de manual em suas configurações do esquema de aplicativo (ver resposta)
runmad
@runmad ver comentário na resposta
Papai Noel
@HaimBenchimol Djd, você recebe uma resposta ao seu relatório de erros? Não cheguei a preencher meu próprio relatório de erro.
Papai Noel

Respostas:

215

UPDATE2:

Você pode conseguir isso usando a nova estrutura PushKit, introduzida no iOS 8. Embora o PushKit seja usado para VoIP. Portanto, seu uso deve ser relacionado a VoIP, caso contrário, há risco de rejeição do aplicativo. (Veja esta resposta ).


UDPDATE1:

A documentação foi esclarecida para iOS8 . A documentação pode ser lida aqui . Aqui está um trecho relevante:

Use este método para processar notificações remotas recebidas para seu aplicativo. Diferente do application:didReceiveRemoteNotification:método, chamado apenas quando o aplicativo está sendo executado em primeiro plano, o sistema chama esse método quando o aplicativo está sendo executado em primeiro plano ou em segundo plano. Além disso, se você ativou o modo de segundo plano de notificações remotas, o sistema inicia o aplicativo (ou o ativa do estado suspenso) e o coloca no estado de segundo plano quando chega uma notificação por push. No entanto, o sistema não inicia seu aplicativo automaticamente se o usuário forçar o encerramento. Nessa situação, o usuário deve reiniciar seu aplicativo ou reiniciar o dispositivo antes que o sistema tente iniciar seu aplicativo automaticamente novamente.


Embora isso não tenha sido esclarecido pelo vídeo da WWDC, uma rápida pesquisa nos fóruns de desenvolvedores revelou isso:

https://devforums.apple.com/message/873265#873265 (login obrigatório)

Lembre-se também de que, se você matar seu aplicativo pelo alternador de aplicativos (ou seja, deslizar para cima para matar o aplicativo), o SO nunca reiniciará o aplicativo, independentemente de notificação por push ou busca em segundo plano. Nesse caso, o usuário precisa reiniciar manualmente o aplicativo uma vez e, a partir desse momento, as atividades em segundo plano serão invocadas. - pmarcos

Esse post foi de um funcionário da Apple, então acho que posso confiar que essas informações estão corretas.

Portanto, parece que quando o aplicativo é eliminado do alternador de aplicativos (deslizando para cima), o aplicativo nunca será iniciado, mesmo para buscas programadas em segundo plano.

Papai Noel
fonte
2
Para mim, adicionar a ação em "didFinishLaunchingWithOptions" ao iniciar as opções não é nulo. Eu tenho o mesmo método aqui como em "didreceiveRemoteNotification"
harsh.prasad
@ harsh.prasad isso é interessante. O problema é que o aplicativo não é iniciado quando o aplicativo é eliminado do alternador de aplicativos.
Papai Noel
3
O aplicativo não precisa ser mostrado no alternador de aplicativos se um push silencioso for recebido. Ele pode ser iniciado em segundo plano sem adicioná-lo ao alternador de aplicativos, e pode executar e "fazer o que quiser" e sair. Os aplicativos que permanecem ativos por muito tempo são eliminados da mesma maneira que já são.
precisa saber é o seguinte
1
@chrizstone A solução é que esse comportamento seja intencional e você não possa fazer nada a respeito.
Papai Noel
1
@JPK Uh, as notificações por push não são afetadas. É apenas executar tarefas em segundo plano que não funcionarão depois que for forçado a sair.
Papai Noel
70

Você pode alterar as configurações de inicialização do seu destino em "Gerenciar esquema" para Wait for <app>.app to be launched manually, o que permite a depuração configurando um ponto de interrupção application: didReceiveRemoteNotification: fetchCompletionHandler:e enviando a notificação por push para acionar a inicialização em segundo plano.

Não tenho certeza de que resolverá o problema, mas isso pode ajudá-lo na depuração no momento.

captura de tela

runmad
fonte
de modo que este ajudou, mas o problema ainda existe
Papai Noel
Estranho. Presumo que você tenha mais do que verificado duas vezes, todo o flash está definido em sua lista, etc.?
runmad
Além disso, eu sei que tenho tudo certo, porque quando o aplicativo está em segundo plano, tudo funciona perfeitamente. É justamente quando o aplicativo não está sendo executado de maneira alguma.
Papai Noel
Gostaria de saber se um gatilho de lançamento de notificação por push é determinado pelo sistema. Por exemplo, se o iOS determinar que não é um bom momento para iniciar o aplicativo no momento, ele poderá ser adiado para mais tarde. Talvez tente fechar todos os aplicativos em execução / em segundo plano e veja o que acontece? Estou apenas adivinhando neste momento: - /
runmad
apenas tentei isso. Nada aconteceu, como sempre. Eu poderia perguntar nos fóruns de desenvolvimento.
Papai Noel
37

A resposta é SIM, mas não deve usar 'Busca em segundo plano' ou 'Notificação remota'. PushKit é a resposta que você deseja.

Em resumo, o PushKit, a nova estrutura do ios 8, é o novo mecanismo de notificação por push que pode iniciar silenciosamente seu aplicativo em segundo plano, sem nenhum aviso visual de alerta, mesmo que seu aplicativo tenha sido eliminado ao deslizar para fora do alternador de aplicativos, surpreendentemente você nem consegue vê-lo. do alternador de aplicativos.

Referência PushKit da Apple:

A estrutura PushKit fornece as classes para seus aplicativos iOS receberem push de servidores remotos. Os impulsos podem ser de um de dois tipos: padrão e VoIP. Os push padrão podem entregar notificações, como nas versões anteriores do iOS. Os push de VoIP fornecem funcionalidade adicional além do envio padrão necessário aos aplicativos de VoIP para executar o processamento sob demanda do envio antes de exibir uma notificação ao usuário.

Para implantar esse novo recurso, consulte este tutorial: https://zeropush.com/guide/guide-to-pushkit-and-voip - Eu testei no meu dispositivo e funciona conforme o esperado.

superZhen
fonte
9
Parece-me que você precisa definir seu aplicativo como usando VoIP. Se o seu aplicativo não for realmente um aplicativo de VoIP, ele não será rejeitado durante a revisão?
precisa saber é o seguinte
6
Infelizmente, conhecendo o processo de validação pela Apple, seria lógico que o aplicativo fosse rejeitado.
Kepa Santos 13/06
3
Usado para VoIP. Se não estiver usando o VoIP para o usuário, isso aumentará muito o risco de rejeição da revisão.
Chris
Parece que grandes fornecedores estão usando esse recurso como uma desculpa para executar coisas em segundo plano e a Apple está com os olhos fechados. Tornando-se o Android um recurso no momento.
TCB13
O PushKit está reservado para VoIP, provedores de arquivos e complicações de exibição. Não está disponível para os casos de uso que esta resposta descreve.
quellish 28/08/18
15

Na verdade, se você precisar testar a busca em segundo plano, precisará ativar uma opção no esquema:

ativando a busca bg

Outra maneira de testá-lo: simular busca bg

A seguir, informações completas sobre esse novo recurso: http://www.objc.io/issue-5/multitasking.html

Danil
fonte
4

Estou tentando diferentes variantes disso há dias, e durante um dia pensei em reiniciar o aplicativo em segundo plano, mesmo quando o usuário passou para matar, mas não, não posso replicar esse comportamento.

É lamentável que o comportamento seja bem diferente do que antes. No iOS 6, se você matasse o aplicativo a partir dos ícones oscilantes, ele ainda seria reativado nos gatilhos do SLC. Agora, se você matar passando, isso não acontece.

É um comportamento diferente, e o usuário, que continuaria recebendo informações úteis do nosso aplicativo se o matasse no iOS 6, agora não o fará.

Precisamos incentivar nossos usuários a reabrirem o aplicativo agora, se eles passaram o dedo para eliminá-lo e ainda esperam um pouco do comportamento de notificação que costumávamos dar a eles. Estou preocupado que isso não seja óbvio para os usuários quando eles deslizarem um aplicativo. Afinal, eles podem estar basicamente limpando ou querendo reorganizar os aplicativos que são mostrados minimizados.

snarshad
fonte
2
Foi exatamente isso que fizemos (applicationWillTerminate), mas não acredito que tenha sido emitida durante a eliminação da memória, pelo menos não no iOS 7. Notei que ela mostrava a notificação antes da reinicialização para uma atualização do sistema operacional, mas é assim raro, não parecia tão ruim.
snarshad
"No iOS 6, se você matasse o aplicativo a partir dos ícones oscilantes, ele ainda seria reativado nos gatilhos do SLC. Agora, se você matar passando o dedo, isso não acontece". Isto não acontecer agora, era uma regressão temporária em uma primeira versão do iOS 7.
funkybro
3

Isso pode ajudá-lo

Na maioria dos casos, o sistema não reinicia os aplicativos depois que eles são forçados a sair pelo usuário. Uma exceção são os aplicativos de localização, que no iOS 8 e posterior são reiniciados após serem encerrados pelo usuário. Em outros casos, porém, o usuário deve iniciar o aplicativo explicitamente ou reiniciar o dispositivo antes que o aplicativo possa ser iniciado automaticamente em segundo plano pelo sistema. Quando a proteção por senha está ativada no dispositivo, o sistema não inicia um aplicativo em segundo plano antes que o usuário desbloqueie o dispositivo pela primeira vez.

Fonte: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Stanislav S.
fonte
3
For **iOS13**

For background PUSHES in iOS13 you must set below parameters
apns-priority = 5
apns-push-type = background
Required for WatchOS
Highly recommended for Other platforms 

EMPURROS de fundo O link do vídeo: https://developer.apple.com/videos/play/wwdc2019/707/

CrazyPro007
fonte
Você pode me compartilhar o link do vídeo, por favor?
guhan0