programing

iPhone 응용 프로그램을 종료하는 올바른 방법은 무엇입니까?

oldcodes 2023. 4. 29. 09:52
반응형

iPhone 응용 프로그램을 종료하는 올바른 방법은 무엇입니까?

아이폰 앱을 프로그래밍하고 있는데 특정 사용자 작업으로 인해 강제 종료해야 합니다.앱이 할당한 메모리를 정리한 후, 앱을 종료하기 위해 호출하는 적절한 방법은 무엇입니까?

아이폰에는 앱을 종료한다는 개념이 없습니다.앱을 종료해야 하는 유일한 작업은 전화기의 홈 버튼을 누르는 것이며, 이는 개발자가 액세스할 수 있는 작업이 아닙니다.

애플에 따르면, 당신의 앱은 스스로 종료되어서는 안 됩니다.사용자가 홈 버튼을 누르지 않았기 때문에 홈 화면으로 돌아갈 때마다 사용자는 앱이 손상된 것처럼 느끼게 됩니다.이는 혼란스럽고 비표준적인 행동이므로 피해야 합니다.

해보셨습니까exit(0)?

에대신,[[NSThread mainThread] exit]더 적절한 해결책인 것처럼 보이려고 노력하지는 않았지만요.

exit(0)사용자에게 충돌로 표시되므로 확인 메시지를 사용자에게 표시합니다.일시 중단된 후(홈 방식으로 누름) 후 사용자합니다.

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

여기에서 Q&A를 확인하십시오. https://developer.apple.com/library/content/qa/qa1561/_index.html

Q: iOS 애플리케이션을 프로그래밍 방식으로 종료하려면 어떻게 해야 합니까?

iOS 애플리케이션을 정상적으로 종료하기 위해 제공되는 API가 없습니다.

iOS에서 사용자는 홈 버튼을 눌러 프로그램을 닫습니다.응용 프로그램에 원하는 기능을 제공할 수 없는 조건이 있는 경우 사용자에게 문제의 특성과 사용자가 취할 수 있는 가능한 조치(WiFi 켜기, 위치 서비스 활성화 등)를 나타내는 경고를 표시하는 것이 좋습니다.사용자의 재량에 따라 응용프로그램을 종료할 수 있습니다.

경고: 전화하지 마십시오.exit기능. 응프램을 호출하는 exit정상 종료를 수행하고 홈 화면으로 애니메이션을 다시 만드는 대신 충돌한 것으로 표시됩니다.

도 있습니다. 데이터가 저장되지 않기 때문입니다.-applicationWillTerminate: 유사한 타기유한사.UIApplicationDelegate종료를 호출하면 메서드가 호출되지 않습니다.

또는 해야 할 에는 다음과 같이 .abort 또는assert 권장

그것은 실제로 프로그램을 그만두는 방법이 아니라 사람들이 그만두도록 강요하는 방법입니다.

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

info.plist로 이동하여 "응용 프로그램이 백그라운드에서 실행되지 않음" 키를 선택합니다.이때 사용자가 홈 버튼을 클릭하면 응용프로그램이 완전히 종료됩니다.

더하다UIApplicationExitsOnSuspendapplication-info.plisttrue.

몇 가지 테스트 후에, 저는 다음과 같이 말할 수 있습니다.

  • : 개인인스용사:[UIApplication sharedApplication]앱이 충돌한 것처럼 보이지만 호출됩니다.- (void)applicationWillTerminate:(UIApplication *)application그렇게 하기 전에;
  • 용사를 exit(0);또한 응용 프로그램을 종료하지만 "정상"으로 표시됩니다(확대 효과와 함께 스프링보드의 아이콘이 예상대로 표시됨). 그러나 호출되지는 않습니다.- (void)applicationWillTerminate:(UIApplication *)application위임 방식

나의 조언:

  1. 으로 수로호로 - (void)applicationWillTerminate:(UIApplication *)application대표로
  2. exit(0);.

사용자가 의도적으로 종료했음을 응용프로그램 대표자에게 알립니다.

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

이 알림을 받으면 그냥 전화합니다.

        exit(0);

모든 일을 할 수 있습니다.그리고 가장 좋은 것은 사용자들이 그만두려고 하는 것입니다. 이것이 바로 사용자들이 그것을 거기에 부르는 것이 문제가 되지 않는 이유입니다.

내 오디오 앱에서는 음악이 재생되는 동안 사람들이 장치를 동기화한 후 앱을 종료해야 했습니다.동기화가 완료되면 바로 알림이 표시됩니다.하지만 그 직후에 앱을 종료하는 것은 실제로 충돌처럼 보일 것입니다.

그래서 대신 다음 백그라운드 작업에서 앱을 종료하도록 플래그를 설정했습니다.동기화 후 앱을 새로 고치는 데 어느 것이 좋습니다.

최근에 내 앱이 거부되었습니다. 문서화되지 않은 방법을 사용했습니다.말 그대로:

"불행히도 개인 API를 사용하고 있기 때문에 앱스토어에 추가할 수 없습니다.iPhone Developer Program License Agreement 3.3.1 섹션에 설명된 바와 같이 공개되지 않는 API의 사용은 금지됩니다.

"3.3.1 애플리케이션은 Apple이 규정한 방식으로만 Documented API를 사용할 수 있으며, 개인 API를 사용하거나 호출해서는 안 됩니다."

애플리케이션에 포함된 비공개 API는 TerminateWithSuccess입니다."

Apple의 의견:

"경고: 종료 기능을 호출하지 마십시오.종료를 호출하는 응용 프로그램은 정상적인 종료를 수행하고 홈 화면으로 애니메이션을 재생하는 대신 충돌한 것으로 나타납니다."

저는 이것이 나쁜 가정이라고 생각합니다.사용자가 종료 단추를 누르면 "응용 프로그램이 종료됩니다."와 같은 메시지가 표시되면 프로그램이 중단되지 않은 것으로 표시됩니다.Apple은 응용 프로그램을 종료할 수 있는 유효한 방법을 제공해야 합니다(종료(0)가 아님).

함를직호안됩는다니서출해접수라고 부르면 안 .exit(0)애플리케이션을 즉시 종료하고 앱이 손상된 것처럼 보이기 때문입니다.따라서 사용자에게 확인 알림을 표시하고 사용자가 직접 확인할 수 있도록 하는 것이 좋습니다.

스위프트 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()
     }
}

이것은 좋은 답변을 얻었지만, 조금 더 확장하기로 결정했습니다.

Apple의 iOS 휴먼 인터페이스 가이드라인을 잘 읽지 않고는 앱스토어에 애플리케이션을 승인할 수 없습니다.(그들은 그들에게 불리한 행동을 한 것에 대해 당신을 거부할 권리를 가지고 있습니다)"프로그램적으로 종료하지 마십시오." 섹션 http://developer.apple.com/library/ios/ #Documentation/UserExperience/Conceptual/Mobile HIG/UEBestPractices/UEBestPractices.html은 이 경우 어떻게 처리해야 하는지에 대한 정확한 지침입니다.

Apple 플랫폼에서 해결책을 쉽게 찾을 수 없는 문제가 발생한 경우 HIG에 문의하십시오.Apple은 단순히 사용자가 이 작업을 수행하지 않기를 원할 수 있으며 일반적으로 (나는 Apple이 아니므로 항상 보장할 수 없습니다) 문서에서 그렇게 말할 수 있습니다.

예를 들어, 인터넷 연결이 필요한 경우 애플리케이션을 종료해야 할 수도 있습니다.알림을 표시한 다음 다음과 같은 작업을 수행할 수 있습니다.

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

다음을 사용하여 앱을 종료할 수 없습니다.exit(0),abort()기능은 Apple이 이러한 기능의 사용을 강력하게 억제하기 때문입니다.개발 또는 테스트 목적으로 이 기능을 사용할 수 있지만,

개발 또는 테스트 중에 응용 프로그램을 종료해야 하는 경우, 중단 기능 또는 매크로를 주장하는 것이 좋습니다.

자세한 내용은 이 Apple Q&A 스레드를 참조하십시오.

이 기능을 사용하면 애플리케이션이 다운되는 듯한 인상을 줍니다.그래서 저는 특정 기능을 사용할 수 없기 때문에 앱을 닫는 것에 대해 알고 있는 사용자에게 종료 메시지와 함께 경고를 표시할 수 있다는 제안을 받았습니다.

그러나 앱을 시작하고 중지하기 위한 iOS 휴먼 인터페이스 가이드라인은 앱을 종료하기 위해 종료 또는 닫기 버튼을 사용하지 말 것을 제안합니다.오히려 그들은 상황을 설명하기 위해 적절한 메시지를 표시할 것을 제안하고 있습니다.

iOS 앱은 닫기 또는 종료 옵션을 표시하지 않습니다.사람들은 다른 앱으로 전환하거나 홈 화면으로 돌아가거나 장치를 절전 모드로 전환할 때 앱 사용을 중지합니다.

iOS 앱을 프로그래밍 방식으로 종료하지 마십시오.사람들은 이것을 충돌로 해석하는 경향이 있습니다.만약 어떤 것이 당신의 앱이 의도한 대로 작동하는 것을 방해한다면, 당신은 사용자들에게 상황에 대해 말하고 그들이 그것에 대해 무엇을 할 수 있는지 설명해야 합니다.

위의 것들 외에도, 좋아요, 제가 덧붙이고 싶은 대답은, 당신의 기억을 정리하는 것에 대해 생각해 보세요.

응용 프로그램이 종료된 후 아이폰 OS는 응용 프로그램에 남아 있는 모든 항목을 자동으로 정리하므로 모든 메모리를 수동으로 해제하면 응용 프로그램이 종료되는 데 걸리는 시간을 늘릴 수 있습니다.

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

저는 위에서 언급한 NSMutableArray new] addObject:nil [접근법을 사용하여 자동 종료(0) 함수 호출을 하지 않고 앱을 강제 종료(크래시)했습니다.

왜냐고요? 제 앱은 중간자 공격을 방지하기 위해 모든 네트워크 API 호출에 대한 인증서 고정을 사용하기 때문입니다.여기에는 시작 시 금융 앱에서 거는 초기화 호출이 포함됩니다.

인증서 인증에 실패하면 모든 초기화 호출이 오류로 인해 앱이 불확실한 상태로 유지됩니다.앱이 OS에 의해 제거되지 않는 한 여전히 초기화되지 않고 신뢰할 수 없기 때문에 사용자를 집으로 보낸 다음 다시 앱으로 되돌리는 것은 도움이 되지 않습니다.

따라서 이 경우 앱이 안전하지 않은 환경에서 작동하고 있음을 사용자에게 알리는 알림을 팝업한 다음 "닫기"를 누르면 위의 방법을 사용하여 앱을 강제로 종료하는 것이 가장 좋습니다.

[[UIApplication sharedApplication] terminateWithSuccess];

잘 작동했고 자동으로 전화가 걸려옵니다.

- (void)applicationWillTerminateUIApplication *)application delegate.

컴파일 시간 경고를 제거하려면 이 코드를 추가합니다.

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

사용자는 앱이 종료되는 시기를 결정해야 합니다.앱이 종료될 때 좋은 사용자 상호 작용이라고 생각하지 않습니다.그러므로 그것을 위한 좋은 API는 없고 오직 홈 버튼에만 하나가 있습니다.

오류가 있는 경우:더 잘 구현하거나 사용자에게 알립니다.다시 시작해야 하는 경우:사용자에게 알림보다 더 잘 구현합니다.

바보처럼 들리지만, 사용자가 결정하도록 하지 않고 그에게 알리지 않고 앱을 종료하는 것은 나쁜 관행입니다.그리고 사용자 상호 작용을 위한 홈 버튼이 있기 때문에 동일한 기능(앱 종료)에 대해 두 가지가 있어서는 안 된다고 애플은 말합니다.

홈 버튼이 아닌 다른 방법으로 앱을 종료하는 은 정말 비 iOS적인 접근 방식입니다.

하지만 저는 사적인 것을 사용하지 않는 도우미를 했습니다.

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

하지만 제 경우에는 여전히 생산을 위한 것이 아닙니다.이는 충돌 보고를 테스트하거나 코어 데이터 재설정 후 신속하게 다시 시작하기 위한 것입니다.생산 코드에 기능이 남아도 거부당하지 않도록 안전하게 했습니다.

예를 들어 위치 업데이트를 받기 위해(위치 업데이트 배경 기능 사용) 백그라운드에서 실행되는 오래 지속되는 앱인 경우 앱을 종료하는 것이 적절할 수 있습니다.

예를 들어 사용자가 위치 기반 앱에서 로그아웃하고 홈 버튼을 사용하여 앱을 백그라운드로 푸시한다고 가정합니다.이 경우 앱이 계속 실행될 수 있지만 앱을 완전히 종료하는 것이 합리적일 수 있습니다.사용자에게 좋고(사용할 필요가 없는 메모리 및 기타 리소스를 해제) 앱 안정성에 좋습니다(즉, 가능한 경우 앱을 주기적으로 다시 시작하는 것이 메모리 누수 및 기타 메모리 부족 문제에 대한 안전망임).

이는 다음과 같은 방법으로 달성할 수 있습니다(아마도 그렇게 해서는 안 될 것입니다:-).

- (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 참조하는 다른 답변에 따르면, 포그라운드에서 실행되는 일반 프로덕션 앱에는 적합하지 않습니다.

Swift 4.2(또는 이전 버전)

이라는 의 도서관Darvin사용할 수 있습니다.

import Darwin

exit(0) // Here you go

NB: iOS 애플리케이션에서는 권장되지 않습니다.

이렇게 하면 충돌 로그가 생성됩니다.

이제 iPadOS 13에서 다음과 같은 모든 장면 세션을 닫을 수 있습니다.

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

을 이전는라고 .applicationWillTerminate(_ application: UIApplication)당신의 앱 위임에 따라 앱을 종료합니다.

하지만 두 가지를 주의해야 합니다.

  • 이것은 확실히 모든 장면을 닫는 데 사용되지 않습니다.(https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multiple-windows/) 참조)

  • 그것은 아이폰의 iOS 13에서 잘 컴파일되고 실행되지만 아무것도 하지 않는 것처럼 보입니다.

iOS/iPadOS 13의 장면에 대한 더 많은 정보: https://developer.apple.com/documentation/uikit/app_and_environment/scenes

언급URL : https://stackoverflow.com/questions/355168/proper-way-to-exit-iphone-application

반응형