Правильный способ выхода из приложения iPhone?

Я программирую приложение для iPhone, и мне нужно заставить его выйти из-за определенных действий пользователя. После очистки памяти выделенное приложение, какой соответствующий метод вызывать для завершения приложения?

Ответ 1

Вы пробовали exit(0)?

Альтернативно, [[NSThread mainThread] exit], хотя я не пробовал, что это похоже на более подходящее решение.

Ответ 2

На iPhone нет концепции выхода из приложения. Единственное действие, которое должно заставить приложение выйти, касается кнопки "Домой" на телефоне, и к тому, что разработчики не имеют доступа.

Согласно Apple, ваше приложение не должно заканчиваться самостоятельно. Поскольку пользователь не нажал кнопку "Домой", любой возврат на главный экран дает пользователю впечатление, что ваше приложение разбилось. Это путаное, нестандартное поведение, и его следует избегать.

Ответ 3

exit (0) появляется пользователю как сбой, поэтому покажите пользователю подтверждение. После подтверждения приостановки (кнопка "домой" нажмите программно) и подождите 2 секунды, пока приложение переходит в фоновый рисунок с анимацией, а затем выйдет за пользовательский вид

-(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);
    }
}

Ответ 4

На самом деле это не выход из программы, а способ заставить людей выйти.

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];

Ответ 5

Проверьте Q & A здесь: https://developer.apple.com/library/content/qa/qa1561/_index.html

В: Как программно выйти из приложения iOS?

Нет никакого API, обеспечивающего изящное завершение приложения iOS.

В iOS пользователь нажимает кнопку "Домой", чтобы закрыть приложения. Если у вашего приложения есть условия, при которых он не может обеспечить свою предполагаемую функцию, рекомендуемый подход заключается в отображении предупреждения для пользователя, которое указывает на характер проблемы и возможные действия, которые может предпринять пользователь, - включение Wi-Fi, включение служб определения местоположения и т.д. Позвольте пользователю прекратить действие приложения по своему усмотрению.

ПРЕДУПРЕЖДЕНИЕ: Не вызывайте функцию exit. Приложения, вызывающие exit, будут отображаться пользователю, чтобы он разбился, вместо того, чтобы выполнять изящное завершение и анимировать обратно на главный экран.

Кроме того, данные не могут быть сохранены, потому что -applicationWillTerminate: и подобные методы UIApplicationDelegate не будут вызываться, если вы вызываете exit.

Если во время разработки или тестирования необходимо прекратить работу приложения, рекомендуется abort или макрос assert

Ответ 6

Перейдите в свой info.plist и проверьте ключ "Приложение не работает в фоновом режиме". На этот раз, когда пользователь нажимает кнопку "домой", приложение полностью завершается.

Ответ 7

Добавьте свойство UIApplicationExitsOnSuspend в application-info.plist в значение true.

Ответ 8

После некоторых тестов я могу сказать следующее:

  • с помощью частного интерфейса: [UIApplication sharedApplication] приведет к сбою приложения, но он будет вызывать - (void)applicationWillTerminate:(UIApplication *)application до этого;
  • с помощью exit(0); также будет прекращено приложение, но оно будет выглядеть "нормальным" (значки трамплинов будут выглядеть как ожидаемые, с эффектом уменьшения), НО он не вызовет метод делегирования - (void)applicationWillTerminate:(UIApplication *)application.

Мой совет:

  • Вручную вызовите - (void)applicationWillTerminate:(UIApplication *)application в делегате.
  • Вызов exit(0);.

Ответ 9

Ваш ApplicationDelegate получает уведомление об умышленном увольнении пользователем:

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

Когда я получаю это уведомление, я просто вызываю

        exit(0);

Что делает вся работа. И самое лучшее, это желание пользователей бросить курить, поэтому это не должно быть проблемой, вызывающей его там.

В моем аудио-приложении необходимо было выйти из приложения после того, как люди синхронизировали свое устройство во время воспроизведения музыки. Как только синхронизация завершена, я получаю уведомление. Но выход из приложения сразу после этого на самом деле будет выглядеть как авария.

Поэтому вместо этого я устанавливаю флаг, чтобы ДЕЙСТВИТЕЛЬНО выйти из приложения при следующем действии фонового действия. Что хорошо для обновления приложения после синхронизации.

Ответ 10

Мое приложение было отклонено недавно bc. Я использовал недокументированный метод. Буквально:

"К сожалению, он не может быть добавлен в App Store, потому что он использует частный API. Использование непубличных API-интерфейсов, которые, как указано в разделе 3.3.1 лицензионного соглашения для разработчиков iPhone, запрещены:

"3.3.1 Приложения могут использовать только Документированные API в порядке, предписываемом Apple, и не должны использовать или использовать какие-либо частные API."

Непубличный API, который включен в ваше приложение, заканчиваетсяWithSuccess "

Ответ 11

Apple говорит:

"Предупреждение: не вызывайте функцию выхода. Приложения, вызывающие exit, будут отображаться пользователю, чтобы он разбился, вместо того, чтобы выполнить изящное завершение и анимировать обратно на главный экран.

Я думаю, что это плохое предположение. Если пользователь нажимает кнопку "Выход" и появляется сообщение, которое говорит что-то вроде: "Приложение теперь уйдет". Оно не разбивается. Apple должна предоставить действительный способ выхода из приложения (не выход (0)).

Ответ 12

Это получило хороший ответ, но решил немного расширить:

Вы не можете получить приложение, принятое в AppStore, без надлежащего изучения Руководства пользователя Apple iOS. (они сохраняют за собой право отклонить вас за что-либо против них). Раздел "Не выходить из программы" http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices.html является точным ориентиром в том, как вы должны лечить в этом случае.

Если у вас возникли проблемы с платформой Apple, вы не можете легко найти решение, обратитесь к HIG. Возможно, Apple просто не хочет, чтобы вы это делали, и они обычно (я не Apple, поэтому я не могу гарантировать всегда), так сказать, в их документации.

Ответ 13

Мы не можем отказаться от приложения, используя функции exit(0), abort(), поскольку Apple решительно препятствует использованию этих функций. Хотя вы можете использовать эти функции для разработки или тестирования.

Если во время разработки или тестирования необходимо прекратить приложение, функция прерывания или макрос утверждения

Чтобы получить дополнительную информацию, найдите этот Apple Q & A.

Как использование этой функции создает впечатление, как приложение терпит крах. Поэтому у меня появилось некоторое предположение, так как мы можем отображать сообщение Alert с сообщением о прекращении доступа к осведомленному пользователю о закрытии приложения из-за недоступности определенных функций.

Но руководство по интерфейсу iOS для Запуск и остановка приложения, предполагая, что Никогда не использовать кнопку "Выход" или "Закрыть" для завершения Заявка. Вместо этого они предлагают отобразить правильное сообщение, чтобы объяснить ситуацию.

Приложение iOS никогда не отображает параметр Close или Quit. Люди перестают использовать приложения, когда они переключаются на другое приложение, возвращаются на главный экран или помещают их устройства в спящем режиме.

Никогда не оставляйте приложение iOS программно. Люди склонны интерпретировать это как катастрофа. Если что-то мешает вашему приложению функционировать как Вы должны сообщить пользователям о ситуации и объяснить, что они могут это сделать.

Ответ 14

В дополнение к вышесказанному, хороший ответ, который я просто хотел добавить, подумайте об очистке памяти.

После выхода приложения iPhone OS автоматически очистит все, что останется у вашего приложения, поэтому освобождение всей памяти вручную может просто увеличить время, в течение которого ваше приложение будет работать.

Ответ 15

Hm, вы можете "выйти" из приложения, если, скажем, для вашего приложения требуется подключение к Интернету. Вы можете отобразить предупреждение, а затем сделать что-то вроде этого:

if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
    [[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
    kill(getpid(), SIGINT); 
}

Ответ 16

- (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);
  }
}

Ответ 17

[[UIApplication sharedApplication] terminateWithSuccess];

Он работал нормально и автоматически вызывает

- (void)applicationWillTerminateUIApplication *)application delegate.

чтобы удалить предупреждение о компиляции, добавьте этот код

@interface UIApplication(MyExtras)
  - (void)terminateWithSuccess;
@end 

Ответ 18

Я использовал упомянутый выше подход [[NSMutableArray new] addObject: nil], чтобы принудительно завершить работу (сбой), не выполняя вызов функции exit-out (0).

Почему? Поскольку мое приложение использует привязку сертификата во всех сетевых API-вызовах, чтобы предотвратить атаки "человек-в-середине". К ним относятся инициализации, которые мое финансовое приложение делает при запуске.

Если аутентификация сертификата не удалась, все мои инициализации вызывают ошибку и оставляют мое приложение в неопределенном состоянии. Разрешение пользователю вернуться домой, а затем обратно в приложение не поможет, так как, если приложение не было очищено ОС, оно все еще неинициализировано и ненадежно.

Итак, в этом случае мы посчитали, что лучше всего появиться предупреждение, информирующее пользователя о том, что приложение работает в ненадежной среде, а затем, когда они нажимают "Закрыть", принудительно выйдите из приложения с использованием вышеупомянутого метода.

Ответ 19

Пользователь должен решить, когда приложение выйдет. Я не думаю, что это хорошее взаимодействие с пользователем, когда приложение завершает работу. Поэтому для него нет приятного API, только домашняя кнопка имеет один.

Если есть ошибка: выполните ее лучше или сообщите об этом пользователю. Если необходимо перезапустить: лучше выполнить уведомление об этом.

Звучит глупо, но плохая практика - выйти из приложения, не позволяя пользователю решить и не уведомить его. А поскольку есть кнопка для взаимодействия с пользователем, Apple заявляет, что не должно быть двух вещей для одной и той же функции (выход из приложения).

Ответ 20

Выйти из приложения иначе, чем кнопка "домой" - это действительно не-iOS-esque.

Я использовал этот помощник, который не использует никаких личных вещей:

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

Но я все еще не предназначен для производства в моем случае. Он предназначен для тестирования отчетов о сбоях или для быстрого перезапуска после Core Data reset. Просто сделал его безопасным, чтобы его не отклонили, если функция оставлена ​​в производственном коде.

Ответ 21

Swift 4.2 (или старше)

Библиотека под названием Darvin может быть использована.

import Darwin

exit(0) // Here you go

NB. Это не рекомендуется в приложениях для iOS.

Делая это, вы получите журнал аварий.

Ответ 22

Вы не должны напрямую вызывать функцию exit(0) как она немедленно выйдет из приложения и будет выглядеть так, как будто ваше приложение не работает. Поэтому лучше показывать пользователям оповещения о подтверждении и позволять им делать это самостоятельно.

Swift 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)
}

Использование:

self.askForQuit { (canQuit) in
     if canQuit {
         self.quit()
     }
}

Ответ 23

Закройте приложение другим способом

Я использовал этот помощник, который не использует никаких личных вещей:

Выход (0);

Ответ 24

Может оказаться целесообразным выйти из приложения, если оно является долговечным приложением, которое также выполняется в фоновом режиме, например, для получения обновлений местоположения (используя для этого возможности фона для обновления местоположения).

Например, скажем, пользователь выходит из вашего приложения на основе местоположения и подталкивает приложение к фону с помощью кнопки "домой". В этом случае ваше приложение может продолжать работать, но имеет смысл полностью выйти из него. Это было бы хорошо для пользователя (освобождает память и другие ресурсы, которые не нужно использовать), и хорошо для стабильности приложения (то есть, если приложение периодически перезапускается, когда это возможно, это защитная сетка от утечек памяти и другой низкой памяти вопросы).

Это может (хотя, вероятно, не должно быть, см. ниже:-) достигается с помощью чего-то вроде:

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

Так как приложение затем выйдет из фонового режима, оно не будет выглядеть неправильно для пользователя и не будет напоминать крах, при условии, что пользовательский интерфейс будет восстановлен при следующем запуске приложения. Другими словами, пользователю он не будет выглядеть иначе, как при запуске приложения, когда приложение находится в фоновом режиме.

Тем не менее, было бы предпочтительнее использовать более стандартный подход, позволяющий системе знать, что приложение может быть прекращено. Например, в этом случае, убедившись, что GPS не используется, прекратив запрашивать обновления местоположения, включая отключение отображения текущего местоположения на карте, если оно присутствует. Таким образом, система позаботится о завершении приложения через несколько минут (т.е. [[UIApplication sharedApplication] backgroundTimeRemaining]) после того, как приложение войдет в фоновый режим. Это принесет все те же преимущества без использования кода для прекращения работы приложения.

- (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.
    }
}

И, конечно, использование exit(0) никогда не будет подходящим для среднего производственного приложения, которое работает на переднем плане, как и другие ответы, ссылающиеся на http://developer.apple.com/iphone/library/qa/qa2008/qa1561.html