Właściwy sposób na zamknięcie aplikacji iPhone'a?

277

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?

użytkownik21293
źródło
34
Jest tylko jeden właściwy sposób - przycisk Home ..
beryl
5
Jedyną sytuacją, jaką mogę sobie wyobrazić, kto rozważa programowe zakończenie pracy, jest następujący scenariusz: Aplikacja uruchamia się, wyświetla warunki użytkowania, odmawia zaakceptowania, a następnie zamyka aplikację. Jest to coś, co marki czasami wywierają na programistę presję. Ale to źle.
Daniel
6
@Daniel Zwykle umieszczasz swoje oświadczenie / warunki użytkowania (EULA) w iTunes, gdy przesyłasz aplikację. Jeśli użytkownik pobierze aplikację, oznacza to, że zaakceptował umowę użytkownika
Paul de Lange
8
Istnieją całkowicie uzasadnione powody, dla których trzeba wymusić zamknięcie aplikacji ios. Mój przypadek polega na tym, że dystrybuuję przedpremierowe wersje beta mojej aplikacji. Wersje beta otwierają wszystkie IAP za darmo. Mają one limit czasowy i muszą wygasnąć po kilku tygodniach. Używam więc poniższej odpowiedzi, aby zabić aplikację po zakończeniu okresu beta. Usunę to w wersji LIVE. Ale i tak odpowiedź pomogła mi i jest poprawna!
badweasel
5
Jednym z ważnych powodów wyjścia z aplikacji jest to, że jest to aplikacja działająca w tle przez długi czas, a aplikacja przechodzi w stan, w którym nie musi już działać w tle. Na przykład użytkownik wylogowuje się. W takim przypadku sensowne byłoby wyjście, aby przy następnym uruchomieniu aplikacja była czysta. To działałoby jako siatka bezpieczeństwa przed wyciekami pamięci, między innymi. Uwaga: w tym przypadku aplikacja wychodziłaby poza tło , więc użytkownik nie zauważyłby nic złego.
frankodwyer

Odpowiedzi:

217

Próbowałeś exit(0)?

Alternatywnie, [[NSThread mainThread] exit]chociaż nie próbowałem, że wydaje się to bardziej odpowiednie rozwiązanie.

Brett
źródło
85
Ponieważ takie postępowanie jest nie do zaakceptowania przez Apple (może spowodować odrzucenie Twojej aplikacji w sklepie z aplikacjami w przypadku niestandardowego interfejsu), rozważ odpowiedź Augusta jako „właściwą”. Do Twojej wiadomości, ta odpowiedź (Bretta) jest poprawna dla WSZYSTKICH programów C i NSThread dla wszystkich programów Cocoa.
Olie,
21
W Q&15 QA1561 firmy Apple zdecydowanie odradza korzystanie z wyjścia, ponieważ wydaje się, że aplikacja uległa awarii. developer.apple.com/iphone/library/qa/qa2008/qa1561.html
program
8
[Wyjście [NSThread mainThread] powoduje awarię aplikacji, ponieważ wyjście nie jest metodą instancji. exit (0) wyśle ​​aplikację w tło w iOS 4. Ponowne wywołanie exit (0) spowoduje jej awarię. Przynajmniej w symulatorze.
user123444555621,
10
Rozumiem, dlaczego tak wielu ludzi odradza to, ale co powiesz nam, by dać programistom trochę uznania? Wszyscy jesteśmy tutaj dorośli i chcemy wiedzieć o tej funkcji. Uważam, że jest to bardzo przydatne w przypadku wewnętrznych kompilacji kontroli jakości i kiedy po raz pierwszy go szukałem, ucieszyłem się z tej „niepoprawnej” odpowiedzi.
evanflash
7
@Kevin „Nie rób tego” nigdy nie jest poprawną odpowiedzią. Podaj ostrzeżenia i zastrzeżenia, jeśli chcesz, ale jedyną prawidłową odpowiedzią na „jak to zrobić” jest „oto jak to zrobić”. Jeśli szukam sposobu na zrobienie czegoś (być może chcę zmusić go do wyjścia podczas debugowania), ludzie słusznie deklarują „nie robisz!” a próba zakopania odpowiedzi, której potrzebuję, to strata czasu. Jakkolwiek wiele osób może mieć złe powody, aby coś zrobić, prawidłowa odpowiedź StackOverflow to ta, która odpowiada na pytanie, ponieważ ludzie z dobrych powodów również znajdą drogę do tego celu.
Glenn Maynard
274

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ć.

sierpień
źródło
13
Jak powiedziałem, jest to zachowanie niestandardowe i należy go unikać. Aplikacje iPhone nie są aplikacjami komputerowymi. Nie traktuj ich jako takich.
sierpień
8
Rozumiem opinię jabłek, ale mam podobną sytuację, moja aplikacja wymaga dostępu do Internetu, jeśli nie jest dostępna, powinni móc wyjść z aplikacji zamiast wyświetlać komunikat o błędzie
Anthony Main
22
Mamy aplikacje, które pomagają ludziom spać. Chcą, aby aplikacja zakończyła się po określonym czasie, aby zmniejszyć zużycie baterii. Myślę, że ten przypadek jest do zaakceptowania - użytkownik ma nadzieję, że śpi i nie może ręcznie zamknąć aplikacji.
JamesSugrue
36
Nadal się nie zgadzam. Po przebudzeniu aplikacja „zniknęła”, co pozwala użytkownikowi zastanawiać się, co się stało. Zamiast tego ustaw w swojej aplikacji licznik czasu, a gdy czas się skończy, bezczynność aplikacji - brak aktywności. Aplikacja, która nie robi absolutnie nic, nie rozładuje baterii. Springboard to także aplikacja - nie wyłącza się tylko w celu oszczędzania energii. Zamiast tego po prostu czeka na dane wprowadzone przez użytkownika.
sierpień
8
To tak naprawdę nie odpowiada na pytanie. Jest w 100% dokładny, ale myślę, że idealnie byłby to komentarz albo do pytania PO, albo do zaakceptowanej odpowiedzi.
Ben Zotto,
49

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

-(IBAction)doExit
{
    //show confirmation message to user
    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Confirmation"
                                                 message:@"Do you want to exit?"
                                                delegate:self
                                       cancelButtonTitle:@"Cancel"
                                       otherButtonTitles:@"OK", nil];
    [alert show];
}

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex != 0)  // 0 == the cancel button
    {
        //home button press programmatically
        UIApplication *app = [UIApplication sharedApplication];
        [app performSelector:@selector(suspend)];

        //wait 2 seconds while app is going background
        [NSThread sleepForTimeInterval:2.0];

        //exit app when app is in background
        exit(0);
    }
}
MaxEcho
źródło
1
Czy Apple zatwierdzi to „wyjście (0)”? Ponieważ niektórzy mówią, że Apple odrzuci twoją aplikację, gdy użyjesz wyjścia 0.
Gajendra K Chauhan
2
@GajendraKChauhan 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.
Eonil
41

Sprawdź pytania i odpowiedzi tutaj: https://developer.apple.com/library/content/qa/qa1561/_index.html

P: Jak programowo wyjść z aplikacji na iOS?

Nie ma interfejsu API umożliwiającego pełne zamknięcie aplikacji na iOS.

W systemie iOS użytkownik naciska przycisk Home, aby zamknąć aplikacje. Jeśli aplikacja ma warunki, w których nie może zapewnić swojej zamierzonej funkcji, zalecanym podejściem jest wyświetlenie ostrzeżenia dla użytkownika, wskazującego charakter problemu i możliwe działania, które użytkownik może podjąć - włączenie Wi-Fi, włączenie usług lokalizacyjnych itp. Pozwól użytkownikowi zakończyć aplikację według własnego uznania.

OSTRZEŻENIE: Nie wywoływaj exitfunkcji. Wywołanie aplikacji exitbędzie wyglądało na to, że użytkownik się zawiesił, zamiast wykonywania pełnego wdzięku zakończenia i animowania z powrotem do ekranu głównego.

Ponadto dane mogą nie zostać zapisane, ponieważ -applicationWillTerminate:i podobne UIApplicationDelegatemetody nie zostaną wywołane, jeśli wywołasz exit.

Jeśli podczas programowania lub testowania konieczne jest zakończenie aplikacji, zalecana jest abortfunkcja lub assertmakro

Wagh
źródło
2
Właśnie dodał AlertView bez przycisków, aby zachować zgodność z tym. Łatwo.
Schultz9999
Świetna odpowiedź, właśnie pracowałem z wyjściem (0) i nie wiedziałem, że należy do prywatnego API
Alex Cio
39

To nie jest tak naprawdę sposób na wyjście z programu, ale sposób zmuszenia ludzi do wyjścia.

UIAlertView *anAlert = [[UIAlertView alloc] initWithTitle:@"Hit Home Button to Exit" message:@"Tell em why they're quiting" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[anAlert show];

źródło
2
Przynajmniej na symulatorze, jeśli to zrobisz, alert będzie nadal wyświetlany, gdy użytkownik ponownie otworzy aplikację. Dlatego sugeruję, aby dać im co najmniej jeden przycisk.
cheshirekow
Użyj odpowiedzi Kalyana, aby aplikacja została zamknięta po naciśnięciu przycisku Home.
Timur Kuchkarov
Problem polega na tym, że tak naprawdę nie wychodzi ona z aplikacji, więc wszystko, co deweloper może chcieć zrobić, wychodząc (wyrzucając nieprawidłowy / stary interfejs użytkownika, usuwając stałe itp.) Nie zostanie wykonane, chyba że użytkownik przesunie aplikację Zamknięte.
Ben Leggiero,
To nie zabija aplikacji.
Dustin,
38

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.

Kalyan
źródło
1
Ale proces w tle również zostaje odrzucony.
Gajendra K Chauhan
17

Dodaj UIApplicationExitsOnSuspendwłaściwość application-info.plistdo true.

Aman Agarwal
źródło
Czy to ustawienie można zmienić w czasie wykonywania? Chodzi mi o to, że chcę żyć w tle, z wyjątkiem sytuacji, gdy moja aplikacja WYBIERA wyjście z następnego zawieszenia - w tym czasie chcę wprowadzić UIApplicationExitsOnSuspend. czy to możliwe?
Motti Shneor
13

Po kilku testach mogę powiedzieć:

  • używając prywatnego interfejsu: [UIApplication sharedApplication]spowoduje, że aplikacja będzie wyglądała na zawieszoną, ALE zadzwoni, - (void)applicationWillTerminate:(UIApplication *)applicationzanim to zrobi;
  • użycie 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 *)applicationmetody delegowania.

Moja rada:

  1. Ręcznie zadzwoń - (void)applicationWillTerminate:(UIApplication *)applicationdo delegata.
  2. Zadzwoń exit(0);.
rchampourlier
źródło
Apple mówi, aby nie używać wyjścia, ponieważ „Aplikacje wywołujące wyjście będą się wyświetlać jako zawieszone, zamiast wykonywać pełne wdzięku zakończenie i animowanie z powrotem do ekranu głównego” developer.apple.com/library/ios/#qa/qa2008/ qa1561.html
MickyD
8

Twoja aplikacjaDelegate otrzymuje powiadomienie o celowym zamknięciu przez użytkownika:

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

Kiedy otrzymam to powiadomienie, po prostu dzwonię

        exit(0);

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.

L'g
źródło
1
To nie jest dobre rozwiązanie, ponieważ aplikacja zrezygnuje z aktywnych z innych powodów, takich jak przychodzące połączenia telefoniczne.
frankodwyer
Rozwiązaniem jest dodanie czeku, który kończy się tylko wtedy, gdy jest to przydatne. Na przykład, jeśli użytkownik jest na ekranie startowym. To jest w porządku, nawet jeśli nadchodzi połączenie telefoniczne. Apple nie odrzucił tego od iOS 2 w moich aplikacjach. stackoverflow.com/a/43906936/712124
cat
6

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
6

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)).

AGPX
źródło
3
Robią to tak, że nazywa się przyciskiem Home, można go znaleźć na dole dowolnego urządzenia iDevice. Z tego powodu nigdy nie trzeba budować własnego przycisku wyjścia.
Popeye
4

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.

nanonyme
źródło
3

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:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
    [[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
    kill(getpid(), SIGINT); 
}
Obrabować
źródło
9
Nie, nie musisz tego kończyć. Na przykład aplikacja iTunes, gdy nie może wykryć prawidłowego połączenia, wyświetla ekran z informacją, że nie ma połączenia. Nie poddaje się, po prostu informuje użytkownika o tym, co się dzieje. Następnie użytkownik kończy pracę, naciskając przycisk Home.
sierpień
1
Aplikacja kompasu kończy pracę, jeśli nie jest w stanie działać.
Josh Lee,
3

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.

Jeśli podczas programowania lub testowania konieczne jest zakończenie aplikacji, zaleca się funkcję przerwania lub makro makra

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ę.

Aplikacja na iOS nigdy nie wyświetla opcji Zamknij ani Wyjdź. Ludzie przestają korzystać z aplikacji, gdy przechodzą do innej aplikacji, wracają do ekranu głównego lub przełączają urządzenia w tryb uśpienia.

Nigdy nie zamykaj programowo aplikacji na iOS. Ludzie mają tendencję do interpretowania tego jako katastrofy. Jeśli coś uniemożliwi działanie aplikacji zgodnie z przeznaczeniem, musisz poinformować użytkowników o sytuacji i wyjaśnić, co mogą z tym zrobić.

technerd
źródło
2

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.

Chris Jefferson
źródło
Zmodyfikuj swoją odpowiedź w bieżącym scenariuszu IOS4.0 i nowszych ..: P
rptwsthi
2
- (IBAction)logOutButton:(id)sender
{
   //show confirmation message to user
   CustomAlert* alert = [[CustomAlert alloc] initWithTitle:@"Confirmation" message:@"Do you want  to exit?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
   alert.style = AlertStyleWhite;
   [alert setFontName:@"Helvetica" fontColor:[UIColor blackColor] fontShadowColor:[UIColor clearColor]];
   [alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

   if (buttonIndex != 0)  // 0 == the cancel button
   {
      //home button press programmatically
      UIApplication *app = [UIApplication sharedApplication];
      [app performSelector:@selector(suspend)];
      //wait 2 seconds while app is going background
      [NSThread sleepForTimeInterval:2.0];
      //exit app when app is in background
      NSLog(@"exit(0)");
      exit(0);
  }
}
Prabhu Natarajan
źródło
1

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.

Michael Long
źródło
Nie widzę, co powstrzymuje cię przed wyświetleniem jednego, zwykłego, pełnoekranowego alertu, informującego użytkownika, że ​​aplikacja nie nadaje się do użytku z powodów „przypinania certyfikatu” i to wszystko. Użytkownik ostatecznie zamknie aplikację. Być może nie wiesz, ale iOS zastrzega sobie prawo do zabicia Twojego procesu (utrzymania jego stanu) i przywrócenia go później, a „cykl życia” aplikacji iOS tak naprawdę nie jest w twoich rękach. Awaria - to po prostu awaria, a system operacyjny może zrezygnować z jej przywrócenia.
Motti Shneor
Wow, trzyletni post. W każdym razie nowa architektura aplikacji praktycznie to robi, za pomocą przycisku ponawiania, który ponawia czynność interfejsu API i albo opuszcza ekran bloku, albo przywraca go do ekranu bloku z nowym błędem.
Michael Long
Stara struktura aplikacji praktycznie nie pozwalała na żaden dobry sposób na ponowne uruchomienie startowych wywołań API, a aplikacja była bez nich niespójna. Mogliśmy użyć stałego ekranu blokady, ale wymagało to od użytkownika samodzielnego zamknięcia aplikacji i zdecydowano, że nie każdy użytkownik wiedział, JAK dwukrotnie kliknąć i wymusić zamknięcie aplikacji. Łatwiej dzisiaj, ale całkiem ukryty trzy lata temu.
Michael Long
1
[[UIApplication sharedApplication] terminateWithSuccess];

Działa dobrze i automatycznie dzwoni

- (void)applicationWillTerminateUIApplication *)application delegate.

aby usunąć ostrzeżenie o czasie kompilacji, dodaj ten kod

@interface UIApplication(MyExtras)
  - (void)terminateWithSuccess;
@end 
siedmiodniowa żałoba
źródło
5
To prywatna metoda, Diego Mercado wyjaśnił powyżej, że jego aplikacja została odrzucona, więc po co ryzykować.
RVN
Użyj prywatnego interfejsu API spowoduje odrzucenie aplikacji przez Apple.
ZYiOS,
2
w przypadku aplikacji dla przedsiębiorstw - może to być rozwiązanie.
user1140780,
- (IBAction) exitApp: (id) nadawca {Selektor SEL = NSSelectorFromString (@ „terminateWithSuccess”); [self performSelector: selektor withObject: [UIApplication sharedApplication]]; }
unom
@unmircea czy ta recenzja przeszła pozytywnie?
Awesome-o
1

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

func askForQuit(_ completion:@escaping (_ canQuit: Bool) -> Void) {
    let alert = UIAlertController(title: "Confirmation!", message: "Do you want to quit the application", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: { (action) in
        alert.dismiss(animated: true, completion: nil)
        completion(true)
    }))
    alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: { (action) in
        alert.dismiss(animated: true, completion: nil)
        completion(false)
    }))
    self.present(alert, animated: true, completion: nil)
}

/// Will quit the application with animation
func quit() {
    UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
    /// Sleep for a while to let the app goes in background
    sleep(2)
    exit(0)
}

Stosowanie:

self.askForQuit { (canQuit) in
     if canQuit {
         self.quit()
     }
}
Tygrys
źródło
0

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).

Binarian
źródło
0

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:

void crash()
{ [[NSMutableArray new] addObject:NSStringFromClass(nil)]; }

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.

Geri Borbás
źródło
0

Swift 4.2 (lub starszy)

Wywoływana biblioteka Darvinmoże być używana.

import Darwin

exit(0) // Here you go

Uwaga: nie jest to zalecane w aplikacjach na iOS.

W ten sposób otrzymasz dziennik awarii.

Saranjith
źródło
0

W iPadOS 13 możesz teraz zamknąć wszystkie sesje scen w następujący sposób:

for session in UIApplication.shared.openSessions {
    UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
}

Spowoduje to wezwanie applicationWillTerminate(_ application: UIApplication)delegata aplikacji i zakończenie aplikacji na końcu.

Ale uwaga na dwie rzeczy:

Więcej informacji o scenach w iOS / iPadOS 13: https://developer.apple.com/documentation/uikit/app_and_environment/scenes

Klaas
źródło
-1

Wyjdź z aplikacji w inny sposób

Zrobiłem jednak tego pomocnika, który nie używa żadnych prywatnych rzeczy:

Wyjdź (0);

iOS.j
źródło
-1

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:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if (/* logged out */) {
        exit(0);
    } else {
       // normal handling.
    }
}

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.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if (/* logged out */) {
       // stop requesting location updates if not already done so
       // tidy up as app will soon be terminated (run a background task using beginBackgroundTaskWithExpirationHandler if needed).
    } else {
       // normal handling.
    }
}

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

frankodwyer
źródło