스크린 샷의 iOS 감지?


135

App Store 의 앱 Snapchat 은 사진을 자기와 함께 공유 할 수있는 앱입니다. X 초 동안 만 사진을 볼 수 있습니다. 홈 전원 키 콤보를 사용하여 사진이 표시되는 동안 스크린 샷을 찍으려고하면 보낸 사람에게 스크린 샷을 찍으라고 알려줍니다.

SDK의 어떤 부분에서 사용자가 스크린 샷을 찍고 있는지 감지 할 수 있습니까? 나는 이것이 가능하다는 것을 몰랐다.


1
stackoverflow.com/questions/2121970/… , 스크린 샷을 찍기 전에 -applicationDidEnterBackground :를 호출하는 데 사용 된 것 같습니다. 지금은 확실하지 않습니다.
— iDev

여러분 다른 스레드에 대한 답변은 stackoverflow.com/questions/2121970/…
— me2

1
이것도 확인하십시오. stackoverflow.com/a/8711894/1730272 더 이상 불가능하다고 말합니다. 아마 당신은 그것을 시도하고 우리에게 알려주십시오.
— iDev November

아직 인터넷 어디에서나 언급 한 것을 보지 못했지만 Xcode를 사용하여 (주최자 창의 장치에서) 스크린 샷을 찍는 경우 앱이 알 수있는 방법이 전혀 없다고 가정합니다. 수신 된 Snapchat 사진을 보는 동안 추가 된 모든 사진에 대해 카메라 롤을 모니터링하고 Xcode를 통해 스크린 샷을 찍으면이 모든 것이 우회됩니다 (감옥 필요 없음).
— smileyborg

후속 조치 : 이 이론을 테스트하고 앱이 Xcode 스크린 샷을 감지하지 못했음을 확인했습니다. 그러나 흥미로운 점은 iOS 6에서 앱에 사진에 액세스 할 수있는 권한이 명시 적으로 부여되어야한다는 것을 깨달았습니다. 그러나이 앱은 여전히 ​​사진에 액세스 할 수없는 스크린 샷을 감지합니다! 감지를 위해 다른 방법을 사용해야합니다. Home + Sleep 버튼 방법을 사용할 때 활성 사진도 화면에서 제거됩니다. 따라서 GestureRecognizer를 사용하여 앱이 안정적으로 모니터링 할 수있는이 스크린 샷 프로세스와 관련된 패턴이 있어야합니까?
— smileyborg

답변:


22

나는 답을 찾았다 !! 스크린 샷을 찍으면 화면에있는 모든 터치가 중단됩니다. 이것이 바로 스냅 챗이 사진을보기 위해 들고 있어야하는 이유입니다. 참조 : http://tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat


15
iOS 7에서는 더 이상 적용되지 않습니다 . iOS7 + 솔루션 은 아래 를 참조하십시오 .
— Joe Masilotti

6
조가 한 말이 맞습니다. 요청자는이를 정답으로 선택 해제해야합니다.
— 비스킷의 신

UIApplication 사용자는 7+ .. 알림이 사용할 수있는 아이폰 OS를 스크린 샷을 가지고나요
— 아 미트 Tandel에게

353

iOS 7부터 다른 답변은 더 이상 사실이 아닙니다. Apple은 touchesCancelled:withEvent:사용자가 스크린 샷을 찍을 때 더 이상 호출되지 않도록 했습니다 .

이로 인해 Snapchat이 완전히 중단 될 수 있으므로 새로운 솔루션의 베타 버전이 추가되었습니다. 이제 NSNotificationCenter를 사용하여 UIApplicationUserDidTakeScreenshotNotification에 옵저버를 추가하는 것만 큼 간단 합니다.

예를 들면 다음과 같습니다.

목표 C

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationUserDidTakeScreenshotNotification
                                                  object:nil
                                                   queue:mainQueue
                                              usingBlock:^(NSNotification *note) {
                                                 // executes after screenshot
                                              }];

빠른

NotificationCenter.default.addObserver(
    forName: UIApplication.userDidTakeScreenshotNotification,
    object: nil,
    queue: .main) { notification in
        //executes after screenshot
}

3
이것을 사용하면 touchesCancelled:withEvent:iOS의 모든 (최근) 버전에서 스크린 샷을 감지 할 수 있어야합니다.
— Joshua Gross

46
스크린 샷이 찍히는 것을 막을 수는 없습니다. UIApplication 클래스 참조 : UIApplicationUserDidTakeScreenshotNotification 사용자가 홈 및 잠금 단추를 눌러 스크린 샷을 찍을 때 게시됩니다. 이 알림에는 userInfo 사전이 포함되어 있지 않습니다. 이 알림은 스크린 샷이 생성 된 후에 게시됩니다.
— badweasel

6
@badweasel 맞습니다. 이 알림은 기존의 코코아 명명 규칙을 따른다는 것을 고려할 때 "Did"라는 단어는 해당 사실 이후에 게시됨을 의미합니다. 이 경우 "Will"에 해당하는 것이 없으며 AFAIK는 사용자가 공개 API를 사용하여 스크린 샷을 찍지 못하게 할 방법이 없습니다.
— Mick MacCallum

1
내가 당신에게 +1을주었습니다. 나는 OP 질문을 원래 읽지 않았으며 질문이 무언가를 방지하기 위해 그것을 탐지하는 방법이라고 생각했습니다. 그것이 내가 찾고있는 것이기 때문입니다. 그래서 나는이 질문에 오는 많은 사람들이 그 대답을 찾고 있기 때문에 주석에 설명을 추가했습니다. 나는 "did"라는 단어에서뿐만 아니라 문서를 통해 더 명확하게 가정했습니다. 내 응용 프로그램에서 사람들이 사진을 편집 할 수있게하지만 일부 도구에는 IAP가 필요합니다. 그러나 나는 그들이 구매하기 전에 시도하게했다. 그래서 워터 마크를 추가하기 위해 캡처되기 전에 감지하고 싶었습니다. 할 수 없습니다.
— badweasel

1
@MickMacCallum 메인 대기열에서 특정 이유가 있습니까?
— kidsid49

13

클로저로 Swift에서 수행하는 방법은 다음과 같습니다.

func detectScreenShot(action: () -> ()) {
    let mainQueue = NSOperationQueue.mainQueue()
    NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationUserDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
        // executes after screenshot
        action()
    }
}

detectScreenShot { () -> () in
    print("User took a screen shot")
}

스위프트 4.2

func detectScreenShot(action: @escaping () -> ()) {
    let mainQueue = OperationQueue.main
    NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: mainQueue) { notification in
        // executes after screenshot
        action()
    }
}

이것은 다음의 표준 기능으로 포함됩니다.

https://github.com/goktugyil/EZSwiftExtensions

면책 조항 : 내 레포


이봐, 나는 이것을 시도하고 훌륭하게 작동했지만 코드에서 무슨 일이 일어나고 있는지 설명 할 수 있습니까? 나는 Swift를 처음 접했고 읽기가 조금 어렵습니다.
— 23:50에

이것은 "작동하면 엉망이되지 않는"종류의 코드 중 하나입니다. 여기에 사용 된 프레임 워크가 매우 드물게 발생하는 원인을 알 필요는 없습니다.
— Esqarrouth

그러나 그 부분을 모른다면 클로저가 어떻게 작동하는지 확인해야합니다. 기본적으로 화면 캡처 기능을 호출 할 때,
— 패러 틴에 넣은

@Esqarrouth 메인 대기열에서 특정 이유가 있습니까?
— kidsid49

복사 붙여 넣기의 원인
— Esqarrouth

4

최근 SWIFT 3 :

func detectScreenShot(action: @escaping () -> ()) {
        let mainQueue = OperationQueue.main
        NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot, object: nil, queue: mainQueue) { notification in
            // executes after screenshot
            action()
        }
    }

에 의 viewDidLoad ,이 함수를 호출

detectScreenShot { () -> () in
 print("User took a screen shot")
}

하나,

NotificationCenter.default.addObserver(self, selector: #selector(test), name: .UIApplicationUserDidTakeScreenshot, object: nil)

    func test() {
    //do stuff here
    }

완전히 잘 작동합니다. mainQueue의 포인트가 보이지 않습니다 ...


문제는 스크린 샷을 만들기 전에 알림을받는 방법을 묻는 것입니다. 이것은 촬영 후 알려줍니다 .
— rmaddy

1
@rmaddy 그 질문은 어디에서 알림을 받는지 묻는 것 어디에서 보았습니까? 당신의 의견 의도가 확실하지 않은, 나는 단지 위의 대답을 개선했습니다 ..
— Maksim Kniazev

질문은 "사용자가 스크린 샷을 찍고 있음을 감지합니다" 입니다. OP가 사실을 알고 자한다면 질문은 "사용자가 스크린 샷을 찍었 음을 감지합니다" 여야합니다 .
— rmaddy

1

사용자가 도청했는지 여부를 감지하는 직접적인 방법이없는 것 같습니다 home + power button. 당 이 , 그것은 다윈 알림을 사용하여 이전에 가능했다, 그러나 그것은 더 이상 작동하지 않습니다. snapchat은 이미 그것을하고 있기 때문에 10 초 사이에 새로운 사진이 추가되었는지 감지하기 위해 iPhone 사진 앨범을 확인하고 어쨌든 현재 표시된 이미지와 비교하고 있습니다. 이 비교를 위해 일부 이미지 처리가 수행 될 수 있습니다. 그냥 생각, 아마 당신은 그것을 작동하게 확장 할 수 있습니다. 자세한 내용은 이것을 확인 하십시오 .

편집하다:

UITouch 취소 이벤트를 감지하고 (스크린 캡처가 터치를 취소 함)이 블로그에 따라이 오류 메시지를 사용자에게 표시하는 것 같습니다. 를 감지 iOS에서 스크린 샷을 감지하는 방법 (예 : SnapChat)

이 경우 – touchesCancelled:withEvent:UITouch 취소를 감지하여이를 감지하는 방법을 사용할 수 있습니다 . 이 위임 방법에서 이미지를 제거하고 사용자에게 적절한 경고를 표시 할 수 있습니다.

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesCancelled:touches withEvent:event];

    NSLog(@"Touches cancelled");

    [self.imageView removeFromSuperView]; //and show an alert to the user
}

당신은 이것에 대한 확실한 대답을 얻기 위해 올바른 장소에 잘 연결되어있는 것 같습니다;)
— smileyborg

결정적인 대답보다 교육받은 추측에 가깝습니다. 불행히도 나는 이것에 대한 정확한 대답을 얻을 수있는 연결이 없습니다. 그들이 개인 API를 사용하지 않는다면, 이것이 내가 생각할 수있는 유일한 방법입니다. 앨범에 추가 된 이미지를 감지하고 일부 알고리즘을 기반으로 해당 이미지를 화면의 현재 이미지와 비교합니다.
— iDev December

그러나 장치의 사진 및 카메라 롤에 대한 액세스를 요청하지 않고도이 작업을 수행 할 수 있다면 다른 것이 아니라고해야합니까? 내 이론은 수신 된 사진 메시지를 길게 눌러 볼 수 있다는 사실과 관련이 있으며 Home + Lock버튼 을 누를 때 화면에 손가락이 닿지 않는 것처럼 OS가 즉시 작동 한다는 사실과 관련 이 있습니다. 어쩌면 이것은 touchesEnded:withEvent평소와 같이 (또는 비슷한 콜백) 없이 발생할 수 있으므로이 독특한 패턴의 이벤트를 모니터링 할 수 있습니까? 나는 완전히 틀린 길을 가고 있을지도 모르지만, 지금은 이것이 나의 유일한 이론이다.
— smileyborg

화면에 손가락을 대고 들지 말고 다른 두 버튼을 누를 수 있는지보십시오. 그것은 여전히 ​​내가 추측하는 메시지를 보여주고 있었다. 그래서 그들은 개인 API를 사용하고 어떻게 든 앱 스토어에 넣었을 수 있습니다.
— iDev December

2

1

스위프트 4+

NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: OperationQueue.main) { notification in
           //you can do anything you want here. 
        }

이 관찰자를 사용하면 사용자가 스크린 샷을 찍는시기를 알 수 있지만 그를 막을 수는 없습니다.


0

스위프트 4 예제

클로저를 사용한 예제 # 1

NotificationCenter.default.addObserver(forName: .UIApplicationUserDidTakeScreenshot, 
                                       object: nil, 
                                       queue: OperationQueue.main) { notification in
    print("\(notification) that a screenshot was taken!")
}

선택기가있는 예제 # 2

NotificationCenter.default.addObserver(self, 
                                       selector: #selector(screenshotTaken), 
                                       name: .UIApplicationUserDidTakeScreenshot, 
                                       object: nil)

@objc func screenshotTaken() {
    print("Screenshot taken!")
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.