스크린 샷의 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.