Programuję aplikację na iPhone'a i muszę wymusić jej zamknięcie z powodu pewnych działań użytkownika. Po wyczyszczeniu pamięci przydzielonej aplikacji, jaką metodę należy wywołać, aby zakończyć działanie aplikacji?
ios
objective-c
iphone
cocoa-touch
ipad
użytkownik21293
źródło
źródło
Odpowiedzi:
Próbowałeś
exit(0)
?Alternatywnie,
[[NSThread mainThread] exit]
chociaż nie próbowałem, że wydaje się to bardziej odpowiednie rozwiązanie.źródło
Na iPhonie nie ma pojęcia o zamknięciu aplikacji. Jedynym działaniem, które powinno spowodować zamknięcie aplikacji, jest dotknięcie przycisku Początek na telefonie, a programiści nie mają do tego dostępu.
Według Apple'a twoja aplikacja nie powinna zakończyć się sama. Ponieważ użytkownik nie nacisnął przycisku strony głównej, każdy powrót do ekranu głównego powoduje wrażenie, że aplikacja uległa awarii. Jest to mylące, niestandardowe zachowanie, którego należy unikać.
źródło
wyjście (0) pojawia się użytkownikowi jako awaria, więc pokaż mu komunikat potwierdzający. Po potwierdzeniu wstrzymaj (przycisk Home naciśnij programowo) i poczekaj 2 sekundy, aż aplikacja przejdzie w tło z animacją, a następnie wyjdź za widok użytkownika
źródło
exit(0)
nie ma znaczenia. Chodzi o to, że Twoja aplikacja „zachowuje się podczas rzucania”. Samo rzucanie zachowania jest zabronione w AppStore, z wyjątkiem kilku aplikacji tworzonych przez bardzo ważne firmy zewnętrzne. Również naśladowanie zachowania przycisku Home również podlega odrzuceniu.Sprawdź pytania i odpowiedzi tutaj: https://developer.apple.com/library/content/qa/qa1561/_index.html
źródło
To nie jest tak naprawdę sposób na wyjście z programu, ale sposób zmuszenia ludzi do wyjścia.
źródło
Przejdź do swojej info.plist i sprawdź klucz „Aplikacja nie działa w tle”. Tym razem, gdy użytkownik kliknie przycisk Początek, aplikacja zostanie całkowicie zamknięta.
źródło
Dodaj
UIApplicationExitsOnSuspend
właściwośćapplication-info.plist
dotrue
.źródło
Po kilku testach mogę powiedzieć:
[UIApplication sharedApplication]
spowoduje, że aplikacja będzie wyglądała na zawieszoną, ALE zadzwoni,- (void)applicationWillTerminate:(UIApplication *)application
zanim to zrobi;exit(0);
spowoduje również zamknięcie aplikacji, ale będzie wyglądać „normalnie” (ikony trampoliny wyglądają zgodnie z oczekiwaniami, z efektem pomniejszenia), ALE nie wywoła- (void)applicationWillTerminate:(UIApplication *)application
metody delegowania.Moja rada:
- (void)applicationWillTerminate:(UIApplication *)application
do delegata.exit(0);
.źródło
Twoja aplikacjaDelegate otrzymuje powiadomienie o celowym zamknięciu przez użytkownika:
Kiedy otrzymam to powiadomienie, po prostu dzwonię
Który wykonuje całą pracę. A najlepsze jest to, że useres zamierza rzucić palenie, dlatego nie powinno być problemu z nazwaniem go tam.
W mojej aplikacji audio konieczne było zamknięcie aplikacji po zsynchronizowaniu urządzenia podczas odtwarzania muzyki. Po zakończeniu synchronizacji otrzymuję powiadomienie. Ale zamknięcie aplikacji zaraz po tym wyglądałoby jak awaria.
Zamiast tego ustawiłem flagę, aby NAPRAWDĘ zamknąć aplikację podczas następnej akcji w tle. Co jest w porządku do odświeżenia aplikacji po synchronizacji.
źródło
Moja aplikacja została ostatnio odrzucona, ponieważ użyłem nieudokumentowanej metody. Dosłownie:
„Niestety nie można go dodać do App Store, ponieważ korzysta z prywatnego API. Korzystanie z niepublicznych API, które jest opisane w Umowie licencyjnej na program dla programistów iPhone, sekcja 3.3.1 jest zabronione:
„3.3.1 Aplikacje mogą korzystać z udokumentowanych interfejsów API wyłącznie w sposób określony przez Apple i nie mogą używać ani wywoływać żadnych prywatnych interfejsów API”.
Niepubliczny interfejs API dołączony do aplikacji to terminateWithSuccess ”
źródło
Apple mówi:
„Ostrzeżenie: nie wywoływaj funkcji wyjścia. Aplikacje wywołujące wyjście będą się wyświetlać jako zawieszone, zamiast wykonywać pełne zakończenie działania i animować z powrotem do ekranu głównego.”
Myślę, że to złe założenie. Jeśli użytkownik stuknie przycisk wyjścia, a pojawi się komunikat z napisem: „Aplikacja zostanie teraz zamknięta”, oznacza to, że nie jest zawieszony. Apple powinien zapewnić prawidłowy sposób na zamknięcie aplikacji (nie wychodzić (0)).
źródło
Otrzymał dobrą odpowiedź, ale postanowił nieco rozszerzyć:
Nie możesz zaakceptować swojej aplikacji w AppStore bez dobrego przeczytania Wytycznych Apple dotyczących interfejsu ludzkiego iOS. (zachowują prawo do odrzucenia cię za cokolwiek przeciwko nim). Sekcja „Nie wychodź programowo” http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices. HTML jest dokładną wskazówką, jak należy postępować w tym przypadku.
Jeśli kiedykolwiek masz problem z platformą Apple, na którą nie możesz łatwo znaleźć rozwiązania, skonsultuj się z HIG. Jest możliwe, że Apple po prostu nie chce, abyś to zrobił i zwykle (nie jestem Apple, więc nie mogę zagwarantować, że zawsze), mówią to w swojej dokumentacji.
źródło
Hm, może być konieczne „zamknięcie” aplikacji, jeśli powiedzmy, że aplikacja wymaga połączenia z Internetem. Możesz wyświetlić alert, a następnie zrobić coś takiego:
źródło
Nie możemy zamknąć aplikację za pomocą
exit(0)
,abort()
funkcje, jak Apple zdecydowanie zniechęcać do korzystania z tych funkcji. Chociaż możesz użyć tej funkcji do celów programistycznych lub testowych.Znajdź ten wątek Apple Pytania i odpowiedzi, aby uzyskać więcej informacji.
Korzystanie z tej funkcji powoduje wrażenie, jakby aplikacja ulegała awarii. Mam więc sugestię, że możemy wyświetlić komunikat Alert z zakończeniem, aby poinformować użytkownika o zamknięciu aplikacji z powodu niedostępności niektórych funkcji.
Ale iOS Human Interface Interface Wytyczne dotyczące uruchamiania i zatrzymywania aplikacji , sugerujące, że Nigdy nie używaj przycisku Quit lub Close, aby zakończyć aplikację. Zamiast tego sugerują wyświetlenie odpowiedniego komunikatu wyjaśniającego sytuację.
źródło
Oprócz powyższego, dobrze, odpowiedź, którą chciałem dodać, pomyśl o oczyszczeniu pamięci.
Po zamknięciu aplikacji iPhone OS automatycznie wyczyści wszystko, co pozostawiła aplikacja, więc ręczne zwolnienie całej pamięci może tylko wydłużyć czas potrzebny na zamknięcie aplikacji.
źródło
źródło
Użyłem wspomnianego powyżej [[NSMutableArray new] addObject: nil], aby wymusić zamknięcie aplikacji (awarię) bez wykonywania funkcji kontrolnej exit (0).
Czemu? Ponieważ moja aplikacja używa przypinania certyfikatów do wszystkich wywołań interfejsu API sieci, aby zapobiec atakom typu man-in-the-middle. Obejmują one połączenia inicjalizacyjne, które moja aplikacja finansowa wykonuje podczas uruchamiania.
Jeśli uwierzytelnianie certyfikatu się nie powiedzie, wszystkie moje wywołania inicjujące powodują błąd i pozostawiają moją aplikację w nieokreślonym stanie. Pozwalanie użytkownikowi wrócić do domu, a następnie wrócić do aplikacji, nie pomaga, ponieważ dopóki aplikacja nie zostanie wyczyszczona przez system operacyjny, nadal nie jest inicjowana i nie jest godna zaufania.
Dlatego w tym jednym przypadku uznaliśmy, że najlepiej jest wysłać alert informujący użytkownika, że aplikacja działa w niepewnym środowisku, a następnie, gdy naciśnie przycisk „Zamknij”, wymuś zamknięcie aplikacji przy użyciu wyżej wymienionej metody.
źródło
Działa dobrze i automatycznie dzwoni
aby usunąć ostrzeżenie o czasie kompilacji, dodaj ten kod
źródło
Nie powinieneś bezpośrednio wywoływać funkcji,
exit(0)
ponieważ natychmiast zamknie aplikację i będzie wyglądać, jakby aplikacja uległa awarii. Lepiej więc pokazać użytkownikom alert z potwierdzeniem i pozwolić im to zrobić sami.Szybki 4.2
Stosowanie:
źródło
Użytkownik powinien zdecydować, kiedy aplikacja zostanie zamknięta. Nie sądzę, że jest to dobra interakcja użytkownika, gdy aplikacja kończy pracę. Dlatego nie ma dla niego dobrego API, tylko przycisk Home ma taki.
Jeśli wystąpi błąd: lepiej go zaimplementuj lub powiadom użytkownika. Jeśli konieczne jest ponowne uruchomienie komputera: zaimplementuj go lepiej, powiadamiając użytkownika.
Brzmi głupio, ale złą praktyką jest wyjście z aplikacji bez pozwolenia użytkownikowi na powiadomienie. A ponieważ Apple ma przycisk Home do interakcji z użytkownikiem, nie powinno być dwóch rzeczy dla tej samej funkcji (wychodzenie z aplikacji).
źródło
Wyjście z aplikacji w inny sposób niż przycisk home, jest naprawdę nie-iOS .
Zrobiłem jednak tego pomocnika, który nie używa żadnych prywatnych rzeczy:
Ale nadal nie jest przeznaczony do produkcji w moim przypadku. Służy do testowania raportów o awariach lub szybkiego restartu po resecie danych podstawowych. Po prostu zabezpieczyłem go przed odrzuceniem, jeśli funkcja pozostanie w kodzie produkcyjnym.
źródło
Swift 4.2 (lub starszy)
Wywoływana biblioteka
Darvin
może być używana.Uwaga: nie jest to zalecane w aplikacjach na iOS.
W ten sposób otrzymasz dziennik awarii.
źródło
W iPadOS 13 możesz teraz zamknąć wszystkie sesje scen w następujący sposób:
Spowoduje to wezwanie
applicationWillTerminate(_ application: UIApplication)
delegata aplikacji i zakończenie aplikacji na końcu.Ale uwaga na dwie rzeczy:
Z pewnością nie jest to przeznaczone do zamykania wszystkich scen. (patrz https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multiple-windows/ )
Kompiluje się i działa dobrze na iOS 13 na iPhonie, ale wydaje się, że nic nie robi.
Więcej informacji o scenach w iOS / iPadOS 13: https://developer.apple.com/documentation/uikit/app_and_environment/scenes
źródło
Wyjdź z aplikacji w inny sposób
Zrobiłem jednak tego pomocnika, który nie używa żadnych prywatnych rzeczy:
Wyjdź (0);
źródło
Może być właściwe zamknięcie aplikacji, jeśli jest to aplikacja długotrwała, która również działa w tle, na przykład w celu uzyskania aktualizacji lokalizacji (przy użyciu aktualizacji lokalizacji tle).
Załóżmy na przykład, że użytkownik wylogowuje się z aplikacji opartej na lokalizacji i przesuwa aplikację w tło za pomocą przycisku strony głównej. W takim przypadku Twoja aplikacja może nadal działać, ale warto całkowicie ją zamknąć. Byłoby to dobre dla użytkownika (zwalnia pamięć i inne zasoby, które nie muszą być używane), a także poprawia stabilność aplikacji (tj. Upewnianie się, że aplikacja jest okresowo restartowana, gdy jest to możliwe, stanowi zabezpieczenie przed przeciekami pamięci i innymi brakami pamięci zagadnienia).
Można to (choć prawdopodobnie nie powinno, patrz poniżej :-) osiągnąć za pomocą czegoś takiego:
Ponieważ aplikacja wyjdzie z tła nie będzie wyglądać źle dla użytkownika i nie będzie przypominać awarii, pod warunkiem, że interfejs użytkownika zostanie przywrócony przy następnym uruchomieniu aplikacji. Innymi słowy, dla użytkownika nie wyglądałoby inaczej niż inicjowane przez system zakończenie aplikacji, gdy aplikacja jest w tle.
Nadal jednak lepiej byłoby zastosować bardziej standardowe podejście, aby poinformować system, że aplikacja może zostać zakończona. Na przykład w tym przypadku, upewniając się, że GPS nie jest używany, przerywając żądanie aktualizacji lokalizacji, w tym wyłączając wyświetlanie bieżącej lokalizacji w widoku mapy, jeśli jest obecny. W ten sposób system zajmie się zakończeniem aplikacji kilka minut (tj.
[[UIApplication sharedApplication] backgroundTimeRemaining]
) Po wejściu aplikacji w tło. Przyniosłoby to te same korzyści bez konieczności używania kodu w celu zakończenia aplikacji.I oczywiście używanie
exit(0)
nigdy nie byłoby odpowiednie dla przeciętnej aplikacji produkcyjnej działającej na pierwszym planie, zgodnie z innymi odpowiedziami, które odwołują się do http://developer.apple.com/iphone/library/qa/qa2008/qa1561.htmlźródło