it-swarm.com.ru

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

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

264
user21293

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

Кроме того, [[NSThread mainThread] exit], хотя я не пробовал, что кажется более подходящим решением.

212
Brett

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

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

270
August

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);
    }
}
47
Salim

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

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

Проверьте вопросы и ответы здесь: https://developer.Apple.com/library/content/qa/qa1561/_index.html

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

Не предусмотрено API для изящного завершения приложения iOS.

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

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

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

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

38
Wagh

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

38
Kalyan

Добавьте свойство UIApplicationExitsOnSuspend в application-info.plist к true.

17
Aman Agarwal

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

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

Мой совет:

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

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

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

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

        exit(0);

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

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

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

8
L'g

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

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

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

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

6
user223106

Apple говорит:

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

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

6
AGPX

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

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

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

4
nanonyme

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

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

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

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

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

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

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

3
technerd

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

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

2
Chris Jefferson

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

if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) {
    [[UIApplication sharedApplication] performSelector:@selector(terminate)];
} else {
    kill(getpid(), SIGINT); 
}
2
Rob
- (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);
  }
}
2
Prabhu Natarajan

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

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

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

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

1
Michael Long
[[UIApplication sharedApplication] terminateWithSuccess];

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

- (void)applicationWillTerminateUIApplication *)application delegate.

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

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

Вам не следует напрямую вызывать функцию 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()
     }
}
0
TheTiger

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

Если есть ошибка: лучше ее внедрите или оповестите пользователя. Если должен быть перезапуск: Реализуйте его лучше. Уведомите пользователя.

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

0
Binarian

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

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

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

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

0
Geri

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

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

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

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

0
frankodwyer

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

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

import Darwin

exit(0) // Here you go

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

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

0
Saranjith