Estou programando um aplicativo para iPhone e preciso forçá-lo a sair devido a determinadas ações do usuário. Após limpar a memória que o aplicativo alocou, qual é o método apropriado a ser chamado para encerrar o aplicativo?
ios
objective-c
iphone
cocoa-touch
ipad
user21293
fonte
fonte
Respostas:
Você já tentou
exit(0)
?Como alternativa,
[[NSThread mainThread] exit]
embora eu não tenha tentado, parece a solução mais apropriada.fonte
No iPhone, não existe o conceito de sair de um aplicativo. A única ação que deve fazer com que um aplicativo seja fechado é tocar no botão Início no telefone, e não é a isso que os desenvolvedores têm acesso.
De acordo com a Apple, seu aplicativo não deve terminar sozinho. Como o usuário não pressionou o botão Início, qualquer retorno à tela inicial dá ao usuário a impressão de que seu aplicativo travou. Esse é um comportamento confuso e não padrão e deve ser evitado.
fonte
exit (0) aparece para um usuário como falhas, então mostre uma mensagem de confirmação para o usuário. Após a confirmação, suspenda (pressione o botão home programaticamente) e aguarde 2 segundos enquanto o aplicativo está em segundo plano com animação e saia da visualização do usuário
fonte
exit(0)
não importa. Point é que seu aplicativo tem "comportamento de abandono". O comportamento de desistência é proibido na AppStore, exceto alguns aplicativos criados por terceiros muito importantes. Além disso, imitar o comportamento do botão home também está sujeito a ser rejeitado.Verifique as perguntas e respostas aqui: https://developer.apple.com/library/content/qa/qa1561/_index.html
fonte
Não é realmente uma maneira de sair do programa, mas uma maneira de forçar as pessoas a sair.
fonte
Vá para o seu info.plist e marque a tecla "O aplicativo não é executado em segundo plano". Desta vez, quando o usuário clica no botão inicial, o aplicativo sai completamente.
fonte
Adicione
UIApplicationExitsOnSuspend
propriedadeapplication-info.plist
atrue
.fonte
Após alguns testes, posso dizer o seguinte:
[UIApplication sharedApplication]
fará com que o aplicativo pareça travar, mas chamará- (void)applicationWillTerminate:(UIApplication *)application
antes de fazer isso;exit(0);
também encerrará o aplicativo, mas parecerá "normal" (os ícones do trampolim aparecerão como o esperado, com o efeito de redução de zoom), MAS não chamará o- (void)applicationWillTerminate:(UIApplication *)application
método delegado.Meu conselho:
- (void)applicationWillTerminate:(UIApplication *)application
para o delegado.exit(0);
.fonte
O ApplicationDelegate é notificado sobre a saída intencional do usuário:
Quando recebo esta notificação, ligo apenas
O que faz todo o trabalho. E o melhor é que os usuários pretendem sair, e é por isso que não deve ser um problema chamá-lo para lá.
No meu aplicativo de áudio, era necessário sair do aplicativo depois que as pessoas sincronizavam seus dispositivos enquanto a música ainda estava tocando. Assim que a sincronização é concluída, recebo uma notificação. Mas sair do aplicativo logo depois pareceria um acidente.
Então, em vez disso, defino um sinalizador para REALMENTE sair do aplicativo na próxima ação de segundo plano. Não há problema em atualizar o aplicativo após uma sincronização.
fonte
Meu aplicativo foi rejeitado recentemente porque usei um método não documentado. Literalmente:
"Infelizmente, ele não pode ser adicionado à App Store porque está usando uma API privada. É proibido o uso de APIs não públicas, conforme descrito na seção 3.3.1 do Contrato de licença do programa para desenvolvedores do iPhone:
"3.3.1 Os aplicativos podem usar APIs documentadas apenas da maneira prescrita pela Apple e não devem usar ou chamar APIs privadas."
A API não pública incluída no seu aplicativo é terminateWithSuccess "
fonte
A Apple diz:
"Aviso: não chame a função exit. Os aplicativos que chamam exit parecerão que o usuário travou, em vez de executar uma finalização normal e animar de volta para a tela inicial."
Eu acho que isso é uma suposição ruim. Se o usuário tocar em um botão sair e aparecer uma mensagem dizendo algo como: "O aplicativo agora será encerrado.", Ele não parece estar travado. A Apple deve fornecer uma maneira válida de encerrar um aplicativo (não sair (0)).
fonte
Isso obteve uma boa resposta, mas decidiu expandir um pouco:
Você não pode aceitar seu aplicativo na AppStore sem ler bem as Diretrizes de interface humana para iOS da Apple. (eles se reservam o direito de rejeitá-lo por fazer algo contra eles) A seção "Não saia programaticamente" http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices. html é uma orientação exata sobre como você deve tratar neste caso.
Se você tiver algum problema com a plataforma Apple para o qual não consegue encontrar facilmente uma solução, consulte a HIG. É possível que a Apple simplesmente não queira que você faça isso e eles geralmente (eu não sou a Apple, por isso não posso garantir sempre) o fazem na documentação.
fonte
Hm, talvez você precise sair do aplicativo se, digamos, seu aplicativo exigir uma conexão com a Internet. Você pode exibir um alerta e, em seguida, fazer algo assim:
fonte
Não podemos deixar de aplicativo usando
exit(0)
,abort()
funções, como a Apple fortemente desencorajar o uso dessas funções. Embora você possa usar essas funções para fins de desenvolvimento ou teste.Por favor, encontre este Q&A da Apple tópico de para obter mais informações.
Conforme o uso dessa função, crie uma impressão como se o aplicativo estivesse travando. Então, recebi uma sugestão: podemos exibir Alerta com mensagem de encerramento para o usuário ciente sobre o fechamento do aplicativo, devido à indisponibilidade de determinadas funcionalidades.
Porém, as diretrizes da interface humana do iOS para iniciar e parar o aplicativo sugerem que nunca use o botão Quit ou Close para encerrar o aplicativo. Em vez disso, eles estão sugerindo exibir uma mensagem adequada para explicar a situação.
fonte
Além do que foi dito acima, boa resposta que eu gostaria de acrescentar, pense em limpar sua memória.
Depois que o aplicativo é encerrado, o iPhone OS limpa automaticamente tudo o que for deixado para trás. Portanto, liberar toda a memória manualmente pode aumentar a quantidade de tempo que o aplicativo leva para sair.
fonte
fonte
Usei a abordagem [[NSMutableArray new] addObject: nil] mencionada acima para forçar o encerramento (travamento) do aplicativo sem fazer uma chamada de função de saída de revelador (0).
Por quê? Porque meu aplicativo usa a fixação de certificados em todas as chamadas de API da rede para impedir ataques intermediários. Isso inclui as chamadas de inicialização que meu aplicativo financeiro faz na inicialização.
Se a autenticação do certificado falhar, toda a minha inicialização chamará o erro e deixará meu aplicativo em um estado indeterminado. Deixar o usuário ir para casa e depois voltar para o aplicativo não ajuda, pois, a menos que o aplicativo tenha sido eliminado pelo sistema operacional, ele ainda não foi inicializado e não é confiável.
Portanto, nesse caso, consideramos melhor exibir um alerta informando ao usuário que o aplicativo está operando em um ambiente inseguro e, quando eles pressionam "Fechar", forçam o encerramento do aplicativo usando o método mencionado acima.
fonte
Funcionou bem e chama automaticamente
para remover o aviso de tempo de compilação, adicione este código
fonte
Você não deve chamar diretamente a função
exit(0)
pois ela encerrará o aplicativo imediatamente e parecerá que seu aplicativo falhou. É melhor mostrar aos usuários um alerta de confirmação e permitir que eles façam isso sozinhos.Swift 4.2
Uso:
fonte
O usuário deve decidir quando um aplicativo sai. Não acho que seja uma boa interação do usuário quando um aplicativo é encerrado. Portanto, não há uma API agradável para isso, apenas o botão home possui uma.
Se houver um erro: Implemente melhor ou Notifique o usuário. Se for necessário reiniciar: implemente melhor Notificar o usuário.
Parece idiota, mas é uma prática recomendada sair do aplicativo sem permitir que o usuário decida e sem notificá-lo. E como há um botão home para a interação do usuário, afirma a Apple, não deve haver duas coisas para a mesma função (saindo de um aplicativo).
fonte
Sair de um aplicativo de outra maneira que não o botão de início é realmente uma abordagem que não é do iOS .
Eu fiz esse ajudante, no entanto, que não usa coisas particulares:
Mas ainda não destinado à produção no meu caso. É para testar relatórios de falhas ou para reiniciar rapidamente após uma redefinição dos Dados Principais. Apenas tornou seguro não ser rejeitado se a função permanecesse no código de produção.
fonte
Swift 4.2 (ou mais antigo)
A biblioteca chamada
Darvin
pode ser usada.Nota: isso não é recomendado em aplicativos iOS.
Isso fará com que você registre o erro fatal.
fonte
No iPadOS 13, agora você pode fechar todas as sessões de cena como esta:
Isso chamará
applicationWillTerminate(_ application: UIApplication)
o delegado do aplicativo e o encerrará no final.Mas cuidado com duas coisas:
Certamente não se destina a ser usado para fechar todas as cenas. (consulte https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multiple-windows/ )
Compila e roda bem no iOS 13 em um iPhone, mas parece não fazer nada.
Mais informações sobre cenas no iOS / iPadOS 13: https://developer.apple.com/documentation/uikit/app_and_environment/scenes
fonte
Sair de um aplicativo de outra maneira
Eu fiz esse ajudante, no entanto, que não usa coisas particulares:
Saída (0);
fonte
Pode ser apropriado sair de um aplicativo se for um aplicativo de longa duração que também seja executado em segundo plano, por exemplo, para obter atualizações de local (usando as atualizações de local recurso de segundo plano de para isso).
Por exemplo, digamos que o usuário efetue logout do seu aplicativo com base em localização e empurre o aplicativo para segundo plano usando o botão home. Nesse caso, seu aplicativo pode continuar em execução, mas pode fazer sentido sair completamente dele. Seria bom para o usuário (libera memória e outros recursos que não precisam ser usados) e bom para a estabilidade do aplicativo (ou seja, garantir que o aplicativo seja reiniciado periodicamente sempre que possível, é uma rede de segurança contra vazamentos de memória e outros problemas de memória insuficiente problemas).
Isso poderia (embora provavelmente não deva, veja abaixo :-) ser alcançado com algo como:
Como o aplicativo sairia do segundo plano ele não parecerá errado para o usuário e não se parecerá com uma falha, desde que a interface do usuário seja restaurada na próxima vez em que o aplicativo for executado. Em outras palavras, para o usuário, não pareceria diferente para o encerramento do aplicativo iniciado pelo sistema quando o aplicativo estiver em segundo plano.
Ainda assim, seria preferível usar uma abordagem mais padrão para informar ao sistema que o aplicativo pode ser encerrado. Por exemplo, neste caso, certificando-se de que o GPS não está em uso, parando de solicitar atualizações de localização, incluindo desativar a exibição da localização atual em uma visualização de mapa, se presente. Dessa forma, o sistema cuidará de encerrar o aplicativo alguns minutos (ie
[[UIApplication sharedApplication] backgroundTimeRemaining]
) após o aplicativo entrar em segundo plano. Isso teria os mesmos benefícios sem a necessidade de usar o código para finalizar o aplicativo.E, é claro, o uso
exit(0)
nunca seria apropriado para o aplicativo de produção médio executado em primeiro plano, conforme outras respostas que fazem referência a http://developer.apple.com/iphone/library/qa/qa2008/qa1561.htmlfonte