iOS обнаружение скриншота?

Приложение Snapchat в App Store - это приложение, которое позволяет вам делиться фотографиями с самоуничтожением. Вы можете просматривать фотографии только в течение X секунд. Если вы попытаетесь сделать снимок экрана во время показа изображения с помощью сочетания клавиш домашнего питания, он сообщит отправителю, что вы попытались сделать снимок экрана.

Какая часть SDK позволяет определить, что пользователь делает снимок экрана? Я не знал, что это возможно.

5 ответов

Решение

Я нашел ответ! Снимок экрана прерывает любые прикосновения, которые находятся на экране. Вот почему Snapchat требует удержания, чтобы увидеть картинку. Ссылка: http://tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat

Начиная с iOS 7 другие ответы больше не верны. Apple сделала это так touchesCancelled:withEvent: больше не вызывается, когда пользователь делает снимок экрана.

Это полностью разрушило бы Snapchat, поэтому была добавлена ​​пара бета-версий в новом решении. Теперь решение так же просто, как использование NSNotificationCenter для добавления наблюдателя в UIApplicationUserDidTakeScreenshotNotification.

Вот пример:

Цель С

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

стриж

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

Вот как это сделать в 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")
}

Это включено как стандартная функция в:

https://github.com/goktugyil/EZSwiftExtensions

Отказ от ответственности: это мой репо

Swift 4+

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

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

Последний 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...

Похоже, что нет прямого способа сделать это, чтобы обнаружить, если пользователь нажал на home + power button , Согласно этому, это было возможно раньше с помощью уведомления Дарвина, но это больше не работает. Так как Snapchat уже делает это, я предполагаю, что они проверяют фотоальбом iPhone, чтобы определить, было ли добавлено новое изображение в течение этих 10 секунд, и в некотором смысле они сравниваются с текущим отображаемым изображением. Может быть некоторая обработка изображения сделана для этого сравнения. Просто мысль, возможно, вы можете попытаться расширить это, чтобы оно заработало. Проверьте это для более подробной информации.

Редактировать:

Похоже, что они могут обнаружить событие отмены 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
}

Примеры Swift 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!")
}
Другие вопросы по тегам