[ios] iOS 7 멀티 태스킹 스위처에서 스크린 샷 제어

iOS 7의 새로운 멀티 태스킹 스위처, 특히 앱이 최대 절전 모드로 전환 될 때 OS가 캡처하는 스크린 샷에 대한 정보를 찾으려고 노력하고 있습니다.

여기에 이미지 설명 입력

이 기능이나 스크린 샷을 완전히 끌 수있는 방법이 있습니까? 아니면 스위처에서 앱을 모두 숨길 수 있습니까? 앱은 백그라운드에서 실행되어야하지만 앱의 스크린 샷을 표시하고 싶지 않습니다.

스크린 샷은 잠재적으로 보안 위험이 있으므로 기기의 홈 버튼을 두 번 클릭하는 모든 사람이 카드 번호 또는 계정 요약을 사용할 수있는 뱅킹 앱 라인을 고려하십시오.

이것에 대한 통찰력이있는 사람이 있습니까? 감사.



답변

에서 백그라운드에서 실행 귀하의 UI를 준비 , 애플은 말한다 :

앱 스냅 샷을위한 UI 준비

앱이 백그라운드로 들어가고 델리게이트 메서드가 반환 된 후 UIKit은 앱의 현재 사용자 인터페이스에 대한 스냅 샷을 생성합니다. 시스템은 앱 전환기에 결과 이미지를 표시합니다. 또한 앱을 포 그라운드로 되돌릴 때 일시적으로 이미지를 표시합니다.

앱의 UI에는 비밀번호 나 신용 카드 번호와 같은 민감한 사용자 정보가 포함되어서는 안됩니다. 인터페이스에 이러한 정보가 포함되어 있으면 백그라운드로 들어갈 때보기에서 제거하십시오. 또한 앱의 콘텐츠를 가리는 경고, 임시 인터페이스 및 시스템보기 컨트롤러를 닫습니다. 스냅 샷은 앱의 인터페이스를 나타내며 사용자가 인식 할 수 있어야합니다. 앱이 포 그라운드로 돌아 오면 데이터와 뷰를 적절하게 복원 할 수 있습니다.

기술 Q & A QA1838 : 작업 전환기에 민감한 정보가 나타나지 않도록 방지를 참조하십시오 .

민감한 정보를 모호하게 / 바꾸는 것 외에도을 통해 화면 스냅 샷을 찍지 않도록 iOS 7에 지시 할 수 있습니다 ignoreSnapshotOnNextApplicationLaunch.

앱이 다시 시작될 때 스냅 샷이 앱의 사용자 인터페이스를 올바르게 반영 할 수 없다고 생각되면을 호출 ignoreSnapshotOnNextApplicationLaunch하여 해당 스냅 샷 이미지가 생성되지 않도록 할 수 있습니다 .

그럼에도 불구하고 화면 스냅 샷이 여전히 촬영 된 것으로 보이므로 버그 보고서를 제출했습니다. 그러나 추가로 테스트하고이 설정을 사용하는 것이 도움이되는지 확인해야합니다.

엔터프라이즈 앱인 경우 구성 프로필 참조allowScreenShot제한 페이로드 섹션에 설명 된 적절한 설정을 살펴볼 수도 있습니다 .


여기 내가 필요한 것을 달성하는 구현이 있습니다. 자신의을 제시 UIImageView하거나 위임 프로토콜 패턴을 사용하여 기밀 정보를 가릴 수 있습니다.

//  SecureDelegate.h

#import <Foundation/Foundation.h>

@protocol SecureDelegate <NSObject>

- (void)hide:(id)object;
- (void)show:(id)object;

@end

그런 다음 내 앱 위임에 해당 속성을 부여했습니다.

@property (weak, nonatomic) id<SecureDelegate> secureDelegate;

내 뷰 컨트롤러가 설정합니다.

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
    delegate.secureDelegate = self;
}

뷰 컨트롤러는 분명히 해당 프로토콜을 구현합니다.

- (void)hide:(id)object
{
    self.passwordLabel.alpha = 0.0;
}

- (void)show:(id)object
{
    self.passwordLabel.alpha = 1.0;
}

그리고 마지막으로 내 앱 델리게이트는이 프로토콜과 속성을 자체적으로 사용합니다.

- (void)applicationWillResignActive:(UIApplication *)application
{
    [application ignoreSnapshotOnNextApplicationLaunch];  // this doesn't appear to work, whether called here or `didFinishLaunchingWithOptions`, but seems prudent to include it

    [self.secureDelegate hide:@"applicationWillResignActive:"];  // you don't need to pass the "object", but it was useful during my testing...
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self.secureDelegate show:@"applicationDidBecomeActive:"];
}

다른 사람들이 지적했듯이 앱이 실행되는 동안 홈 버튼을 두 번 탭할 때 후자가 호출되지 않기 때문에 applicationWillResignActive권장되는 대신 사용 applicationDidEnterBackground하고 있습니다.

위임 프로토콜 패턴이 아닌 알림을 사용하여이 모든 것을 처리 할 수 ​​있기를 원하지만 제한된 테스트에서는 알림이 적시에 충분히 처리되지 않지만 위의 패턴은 정상적으로 작동합니다.


답변

이것은 내 응용 프로그램에 대해 작업 한 솔루션입니다.

Tommy가 말했듯이 : applicationWillResignActive를 사용할 수 있습니다. 내가 한 일은 내 SplashImage로 UIImageView를 만들고 그것을 내 주 창에 하위보기로 추가하는 것이 었습니다.

(void)applicationWillResignActive:(UIApplication *)application
{
    imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
    [imageView setImage:[UIImage imageNamed:@"Portrait(768x1024).png"]];
    [self.window addSubview:imageView];
}

홈 버튼을 두 번 탭하면 applicationDidEnterBackground가 트리거되지 않고 applicationWillResignActive가 실행되므로 applicationDidEnterBackground 대신이 메서드를 사용했습니다. 나는 사람들이 다른 경우에도 유발 될 수 있다고 말하는 것을 들었 기 때문에 문제가 있는지 확인하기 위해 여전히 테스트 중이지만 아직까지는 없습니다! 😉

여기에 imageview를 제거하려면 :

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(imageView != nil) {
        [imageView removeFromSuperview];
        imageView = nil;
    }
}

도움이 되었기를 바랍니다!

사이드 노트 : 시뮬레이터와 실제 장치 모두에서 테스트했습니다. 시뮬레이터에는 표시되지 않지만 실제 장치에서는 작동합니다!


답변

이 빠르고 쉬운 방법은 iOS7 이상의 앱 전환기에서 앱 아이콘 위에 검은 색 스냅 샷을 생성합니다.

먼저 앱의 키 창 (일반적으로 application : didFinishLaunchingWithOptions의 AppDelegate.m에 설정 됨)을 가져 와서 앱이 백그라운드로 이동하려고 할 때 숨 깁니다.

- (void)applicationWillResignActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        self.window.hidden = YES;
    }
}

그런 다음 앱이 다시 활성화되면 앱의 키 창 숨기기를 해제합니다.

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        self.window.hidden = NO;
    }
}

이 시점에서 앱 전환기를 확인하고 앱 아이콘 위에 검은 색 스냅 샷이 표시되는지 확인합니다. 앱을 백그라운드로 이동 한 직후에 앱 전환기를 실행하면 앱의 스냅 샷 (숨기고 싶은 앱)이 표시 될 때까지 5 초 정도 지연 될 수 있습니다. 올 블랙 스냅 샷으로 전환됩니다. 지연이 어떻게되는지 잘 모르겠습니다. 누군가 제안 사항이 있으면 차임하십시오.

스위처에서 검은 색 이외의 색상을 원하는 경우 원하는 배경색으로 하위보기를 추가하여 다음과 같이 할 수 있습니다.

- (void)applicationWillResignActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        UIView *colorView = [[[UIView alloc] initWithFrame:self.window.frame] autorelease];
        colorView.tag = 9999;
        colorView.backgroundColor = [UIColor purpleColor];
        [self.window addSubview:colorView];
        [self.window bringSubviewToFront:colorView];
    }
}

그런 다음 앱이 다시 활성화되면이 색상 하위보기를 제거합니다.

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(isIOS7Or8)
    {
        UIView *colorView = [self.window viewWithTag:9999];
        [colorView removeFromSuperview];
    }
}


답변

다음 솔루션을 사용했습니다. 애플리케이션이 사임 할 때 appWindow 스냅 샷을 View로 가져와 흐림을 추가합니다. 그런 다음이 뷰를 앱 창에 추가합니다.

방법 :

  1. 구현 직전에 appDelegate에서 줄을 추가하십시오.

    static const int kNVSBlurViewTag = 198490;//or wherever number you like
  2. 이 방법을 추가하십시오.

    - (void)nvs_blurPresentedView
        {
            if ([self.window viewWithTag:kNVSBlurViewTag]){
                return;
            }
            [self.window addSubview:[self p_blurView]];
        }
    
        - (void)nvs_unblurPresentedView
        {
            [[self.window viewWithTag:kNVSBlurViewTag] removeFromSuperview];
        }
    
        #pragma mark - Private
    
        - (UIView *)p_blurView
        {
            UIView *snapshot = [self.window snapshotViewAfterScreenUpdates:NO];
    
            UIView *blurView = nil;
            if ([UIVisualEffectView class]){
                UIVisualEffectView *aView = [[UIVisualEffectView alloc]initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
                blurView        = aView;
                blurView.frame  = snapshot.bounds;
                [snapshot addSubview:aView];
            }
            else {
                UIToolbar *toolBar  = [[UIToolbar alloc] initWithFrame:snapshot.bounds];
                toolBar.barStyle    = UIBarStyleBlackTranslucent;
                [snapshot addSubview:toolBar];
            }
            snapshot.tag = kNVSBlurViewTag;
            return snapshot;
        }
    
  3. appDelegate 구현을 다음과 같이 만드십시오.

    - (void)applicationWillResignActive:(UIApplication *)application {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
        //...
        //your code
        //...
    
        [self nvs_blurPresentedView];
    }
    
        - (void)applicationWillEnterForeground:(UIApplication *)application {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
        //...
        //your code
        //...
    
        [self nvs_unblurPresentedView];
    }
    

SwiftObjective C로 예제 프로젝트를 만들었습니다 . 두 프로젝트 모두에서 다음 작업을 수행합니다.

-application : didResignActive- 스냅 샷이 생성되고, 흐리게 처리되고, 앱 창에 추가됩니다.

-application : willBecomeActive 블러 뷰가 창에서 제거됩니다.

사용하는 방법:

Objecitve C

  1. AppDelegate+NVSBlurAppScreen프로젝트에 .h 및 .m 파일 추가

  2. -applicationWillResignActive : 메소드에 다음 행을 추가하십시오.

    [self nvs_blurPresentedView];
  3. -applicationDidEnterBackground : 메소드에 다음 행을 추가하십시오.

    [self nvs_unblurPresentedView];

빠른

  1. 프로젝트에 AppDelegateExtention.swift 파일 추가

  2. applicationWillResignActive 함수에서 다음 줄을 추가하십시오.

    blurPresentedView()
  3. applicationDidBecomeActive 함수에 다음 줄을 추가하십시오.

    unblurPresentedView()

답변

함수 에서만 사용 [self.window addSubview:imageView];하는 applicationWillResignActive경우이 imageView는 UIAlertView, UIActionSheet 또는 MFMailComposeViewController를 포함하지 않습니다.

최고의 솔루션은

- (void)applicationWillResignActive:(UIApplication *)application
{
    UIWindow *mainWindow = [[[UIApplication sharedApplication] windows] lastObject];
    [mainWindow addSubview:imageView];
}


답변

이 솔루션은 매우 신뢰할 수 없지만 “답변”으로 내 솔루션을 제공합니다. 가끔 스크린 샷으로 검은 색 화면이 나타나기도하고, 때로는 XIB가 나타나기도하고 앱 자체에서 스크린 샷이 나올 수도 있습니다. 장치 및 / 또는 시뮬레이터에서 실행 여부에 따라 다릅니다.

이 솔루션에는 많은 앱 관련 세부 정보가 포함되어 있으므로 코드를 제공 할 수 없습니다. 그러나 이것은 내 솔루션의 기본 요지를 설명해야합니다.

applicationWillResignActive 아래의 AppDelegate.m에서 iOS7을 실행 중인지 확인하고, 중간에 app-logo가있는 비어있는 새보기를로드합니다. applicationDidBecomeActive가 호출되면 이전 뷰를 다시 시작하여 재설정됩니다.하지만 개발중인 응용 프로그램 유형에 대해 작동합니다.


답변

활성기를 사용하여 홈 버튼의 더블 클릭을 구성하여 멀티 태스킹을 시작하고 홈 버튼의 기본 더블 클릭 및 멀티 태스킹 창 시작을 비활성화 할 수 있습니다. 이 방법은 스크린 샷을 애플리케이션의 기본 이미지로 변경하는 데 사용할 수 있습니다. 이는 기본 암호 보호 기능이있는 앱에 적용됩니다.