iOS-detectie van screenshot?

De app Snapchat, in de App Store, is een app waarmee je deel foto’s met een zelfvernietiging erop. Je kunt de foto’s maar X seconden bekijken. Als je probeert een screenshot te maken terwijl de foto wordt weergegeven met de home-power-toetscombinatie, zal het de afzender vertellen dat je hebt geprobeerd een screenshot te maken.

Met welk deel van de SDK kun je detecteren dat de gebruiker een screenshot maakt? Ik wist niet dat dit mogelijk was.


Antwoord 1, autoriteit 100%

Vanaf iOS 7 zijn de andere antwoorden niet langer waar. Apple heeft het zo gemaakt dat touchesCancelled:withEvent:niet langer wordt aangeroepen wanneer de gebruiker een screenshot maakt.

Dit zou Snapchat in feite volledig breken, dus een paar bèta’s in een nieuwe oplossing werden toegevoegd. Nu is de oplossing zo simpel als het gebruik van NSNotificationCenter om een ​​waarnemer toe te voegen aan UIApplicationUserDidTakeScreenshotNotification.

Hier is een voorbeeld:

Doelstelling C

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

Snel

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

Antwoord 2, autoriteit 7%

Ik heb het antwoord gevonden!! Het maken van een screenshot onderbreekt alle aanrakingen op het scherm. Dit is de reden waarom snapchat moet worden vastgehouden om de foto te zien. Referentie: http://tumblr.jeremyjohnstone.com/post/ 38503925370/hoe-te-detecteren-screenshots-op-ios-achtige-snapchat


Antwoord 3, autoriteit 4%

Zo doe je dat in Swift met sluitingen:

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")
}

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

Dit is een standaardfunctie in:

https://github.com/goktugyil/EZSwiftExtensions

Disclaimer: het is mijn repo


Antwoord 4

Swift 4+

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

door deze waarnemer te gebruiken, kun je erachter komen wanneer de gebruiker een screenshot maakt, maar je kunt hem niet voorkomen.


Antwoord 5

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

Bel deze functie in viewDidLoadaan

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

Echter,

NotificationCenter.default.addObserver(self, selector: #selector(test), name: .UIApplicationUserDidTakeScreenshot, object: nil)
    func test() {
    //do stuff here
    }

werkt helemaal goed. Ik zie geen punten van mainQueue…


Antwoord 6

Het lijkt erop dat er geen directe manier is om dit te doen om te detecteren of de gebruiker op home + power buttonheeft getikt. Volgens ditwas het eerder mogelijk door darwin-melding te gebruiken, maar het werkt niet meer. Omdat snapchat het al doet, denk ik dat ze het iPhone-fotoalbum controleren om te detecteren of er een nieuwe foto is toegevoegd tussen deze 10 seconden, en op de een of andere manier vergelijken ze met de huidige afbeelding die wordt weergegeven. Het kan zijn dat er voor deze vergelijking enige beeldverwerking is gedaan. Gewoon een gedachte, waarschijnlijk kun je proberen dit uit te breiden om het te laten werken. Controleer dit voor meer details.

Bewerken:

Het lijkt erop dat ze de UITouch-annuleringsgebeurtenis detecteren (schermopname annuleert aanrakingen) en deze foutmelding aan de gebruiker tonen volgens deze blog: Hoe screenshots op iOS te detecteren (zoals SnapChat)

In dat geval kunt u de methode – touchesCancelled:withEvent:gebruiken om de UITouch-annulering te detecteren om dit te detecteren. U kunt de afbeelding in deze gedelegeerde methode verwijderen en een passende waarschuwing aan de gebruiker tonen.

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

Antwoord 7

Swift 4 Voorbeelden

Voorbeeld #1 met gebruik van sluiting

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

Voorbeeld #2 met selector

NotificationCenter.default.addObserver(self, 
                                       selector: #selector(screenshotTaken), 
                                       name: .UIApplicationUserDidTakeScreenshot, 
                                       object: nil)
@objc func screenshotTaken() {
    print("Screenshot taken!")
}

Other episodes