Deteksi Layar iOS?

135

Aplikasi Snapchat , di App Store, adalah aplikasi yang memungkinkan Anda berbagi gambar dengan penghancuran sendiri. Anda hanya dapat melihat foto selama X detik. Jika Anda mencoba mengambil tangkapan layar saat gambar ditampilkan menggunakan kombo tombol daya rumah, ia akan memberi tahu pengirim bahwa Anda mencoba mengambil tangkapan layar.

Bagian mana dari SDK yang memungkinkan Anda mendeteksi bahwa pengguna mengambil tangkapan layar? Saya tidak tahu ini mungkin.

saya 2
sumber
1
stackoverflow.com/questions/2121970/… , Sepertinya itu digunakan untuk memanggil -aplikasiDidEnterBackground: sebelum mengambil screenshot sebelumnya. Tidak yakin tentang itu sekarang.
iDev
Kawan Utas lainnya memiliki jawabannya: stackoverflow.com/questions/2121970/…
me2
1
periksa ini juga, stackoverflow.com/a/8711894/1730272 , katanya tidak mungkin lagi. Mungkin Anda bisa mencobanya dan beri tahu kami.
iDev
Belum melihat ini disebutkan di mana pun di Internet, tetapi saya akan berasumsi bahwa jika Anda menggunakan Xcode untuk mengambil tangkapan layar (dari perangkat di jendela Organizer), sama sekali tidak ada cara aplikasi akan dapat mengetahuinya. Itu harus memantau Camera Roll untuk setiap foto yang ditambahkan saat melihat foto Snapchat yang diterima, dan mengambil screenshot melalui Xcode mem-bypass semua ini (tanpa perlu jailbreaking).
smileyborg
Tindak lanjut: Menguji teori ini dan mengkonfirmasi bahwa aplikasi tidak mendeteksi tangkapan layar Xcode. Namun, saya menyadari apa yang menarik adalah bahwa di iOS 6, aplikasi harus secara eksplisit diberikan izin untuk mengakses foto ... namun aplikasi ini masih mendeteksi tangkapan layar tanpa mengizinkannya mengakses foto! Itu harus menggunakan metode lain untuk deteksi - Saya memperhatikan bahwa ketika menggunakan metode tombol Home + Sleep, foto yang aktif juga dihapus dari layar. Jadi harus ada beberapa pola yang terkait dengan proses tangkapan layar ini yang dapat dipantau aplikasi dengan andal, mungkin dengan GestureRecognizer?
smileyborg

Jawaban:

22

Saya menemukan jawabannya !! Mengambil tangkapan layar akan mengganggu setiap sentuhan yang ada di layar. Inilah sebabnya mengapa snapchat membutuhkan penahan untuk melihat gambar. Referensi: http://tumblr.jeremyjohnstone.com/post/38503925370/how-to-detect-screenshots-on-ios-like-snapchat

portforwardpodcast
sumber
15
Tidak lagi benar dengan iOS 7. Lihat di bawah untuk solusi iOS7 +.
Joe Masilotti
6
Apa yang dikatakan Joe benar. Penanya harus menghapus centang ini sebagai jawaban yang tepat.
God of Biscuits
Pengguna UIAplikasi Tidak Mengambil Screenshot Notifikasi dapat digunakan .. iOS 7+
Amit Tandel
353

Pada iOS 7 jawaban lain tidak lagi benar. Apple telah membuatnya jadi touchesCancelled:withEvent:tidak lagi dipanggil saat pengguna mengambil tangkapan layar.

Ini akan memecah Snapchat sepenuhnya secara efektif, sehingga beberapa beta dalam solusi baru ditambahkan. Sekarang, solusinya semudah menggunakan NSNotificationCenter untuk menambahkan pengamat ke UIApplicationUserDidTakeScreenshotNotification .

Ini sebuah contoh:

Tujuan C

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

Cepat

NotificationCenter.default.addObserver(
    forName: UIApplication.userDidTakeScreenshotNotification,
    object: nil,
    queue: .main) { notification in
        //executes after screenshot
}
Mick MacCallum
sumber
3
Menggunakan ini dan touchesCancelled:withEvent:seharusnya memungkinkan Anda untuk mendeteksi tangkapan layar di semua versi (terkini) iOS.
Joshua Gross
46
Ini tidak berfungsi untuk mencegah tangkapan layar diambil. Itu hanya dapat membuat aplikasi tahu bahwa ada yang diambil .. Dari Referensi Kelas UIAplikasi: UIAplikasiUserDidTakeScreenshotNotification Diposting ketika pengguna menekan tombol Rumah dan Kunci untuk mengambil tangkapan layar. Pemberitahuan ini tidak mengandung kamus userInfo. Pemberitahuan ini diposting SETELAH tangkapan layar diambil.
badweasel
6
@badweasel Benar. Mempertimbangkan pemberitahuan ini mengikuti konvensi penamaan Kakao konvensional, kata "Did" menyiratkan bahwa itu diposting setelah fakta. Tidak ada yang setara dengan "Will" dalam kasus ini, dan AFAIK tidak ada cara untuk mencegah pengguna mengambil tangkapan layar menggunakan API publik.
Mick MacCallum
1
Perhatikan bahwa saya memberi Anda +1. Saya telah salah membaca pertanyaan OP awalnya dan berpikir pertanyaannya adalah bagaimana mendeteksi hal itu untuk mencegah sesuatu - karena itulah yang saya cari. Jadi saya hanya menambahkan klarifikasi dalam komentar karena saya berharap banyak orang yang datang ke pertanyaan ini mencari jawaban itu. Saya berasumsi itu juga dari kata "lakukan" tetapi dokumentasi membuatnya lebih jelas. Di aplikasi saya, saya mengizinkan orang mengedit foto tetapi beberapa alat membutuhkan IAP. Tapi saya membiarkan mereka mencoba sebelum membeli. Jadi saya ingin mendeteksi sebelum ditangkap untuk menambahkan tanda air. Tidak bisa dilakukan
badweasel
1
@MickMacCallum Ada alasan khusus Anda melakukannya di antrian utama?
kidsid49
13

Inilah cara melakukan di Swift dengan penutupan:

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

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

Ini termasuk sebagai fungsi standar di:

https://github.com/goktugyil/EZSwiftExtensions

Penafian: Ini repo saya

Esqarrouth
sumber
Hei, saya sudah mencoba ini dan itu berhasil, tetapi bisakah Anda menjelaskan apa yang terjadi dalam kode? Saya baru mengenal Swift dan agak sulit dibaca.
aecend
Ini adalah salah satu dari mereka, "jika berhasil jangan mengacaukannya" jenis kode. Anda tidak perlu belajar apa ini karena kerangka kerja yang digunakan di sini sangat jarang.
Esqarrouth
Tapi Anda harus memeriksa bagaimana penutupan berfungsi jika Anda tidak tahu bagian itu, pada dasarnya ketika Anda memanggil mendeteksi fungsi
tangkapan
@Esqarrouth Ada alasan khusus Anda melakukannya di antrian utama?
kidsid49
Penyebab dari copy paste
Esqarrouth
4

SWIFT 3 terbaru :

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

Di viewDidLoad , panggil fungsi ini

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

Namun,

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

    func test() {
    //do stuff here
    }

bekerja dengan sangat baik. Saya tidak melihat poin dari mainQueue ...

Maksim Kniazev
sumber
Pertanyaannya adalah bagaimana cara diberitahu sebelum tangkapan layar diambil. Ini memberi tahu Anda setelah diambil.
rmaddy
1
@rmaddy di mana Anda melihat pertanyaan itu menanyakan bagaimana cara diberitahukan sebelumnya? Saya hanya meningkatkan jawaban di atas saya, tidak yakin niat komentar Anda ..
Maksim Kniazev
Pertanyaannya bertanya: "mendeteksi bahwa pengguna mengambil tangkapan layar" . Jika OP ingin tahu setelah fakta, pertanyaan harus berbunyi: "mendeteksi bahwa pengguna mengambil tangkapan layar" .
rmaddy
1

Sepertinya tidak ada cara langsung untuk melakukan ini untuk mendeteksi jika pengguna telah mengetuk home + power button. Sesuai ini , itu mungkin sebelumnya dengan menggunakan notifikasi darwin, tetapi tidak berfungsi lagi. Karena snapchat sudah melakukannya, tebakan saya adalah mereka sedang memeriksa album foto iPhone untuk mendeteksi apakah ada gambar baru yang ditambahkan di antara 10 detik ini, dan di suatu tempat mereka membandingkan dengan gambar saat ini yang ditampilkan. Mungkin beberapa pemrosesan gambar dilakukan untuk perbandingan ini. Hanya sebuah pemikiran, mungkin Anda dapat mencoba mengembangkan ini untuk membuatnya bekerja. Periksa ini untuk lebih jelasnya .

Edit:

Sepertinya mereka mungkin mendeteksi acara pembatalan UITouch (Pengambilan layar membatalkan sentuhan) dan menampilkan pesan kesalahan ini kepada pengguna sesuai blog ini: Cara mendeteksi tangkapan layar di iOS (seperti SnapChat)

Jika demikian, Anda dapat menggunakan – touchesCancelled:withEvent:metode untuk merasakan pembatalan UITouch untuk mendeteksi hal ini. Anda dapat menghapus gambar dalam metode delegasi ini dan menunjukkan peringatan yang sesuai kepada pengguna.

- (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
}
iDev
sumber
Anda tampaknya terhubung dengan baik di tempat yang tepat untuk mendapatkan jawaban yang pasti tentang ini;)
smileyborg
Ini lebih merupakan dugaan yang berpendidikan daripada jawaban yang pasti. Sayangnya saya tidak memiliki koneksi untuk mendapatkan jawaban yang pasti untuk ini. Jika mereka tidak menggunakan API pribadi apa pun, itulah satu-satunya cara yang dapat saya pikirkan, untuk melakukan ini. Untuk mendeteksi penambahan gambar ke album dan membandingkan gambar itu dengan gambar saat ini di layar berdasarkan beberapa algoritma.
iDev
Tetapi mengingat mereka dapat melakukan ini tanpa meminta akses ke foto perangkat dan Rol Kamera ... pasti ada yang lain bukan? Teori saya akan terkait dengan fakta bahwa mereka membuat Anda menekan lama pada pesan foto yang diterima untuk melihatnya, dan bahwa ketika Anda menekan Home + Locktombol, OS segera bertindak seolah-olah tidak ada jari yang menyentuh layar. Mungkin ini terjadi tanpa touchesEnded:withEvent(atau panggilan balik serupa) seperti biasanya, jadi mungkin mereka dapat memantau pola acara yang unik ini? Saya mungkin benar-benar di jalur yang salah, tetapi hanya itulah teori saya saat ini.
smileyborg
Letakkan jari di layar dan tanpa mengangkatnya, coba jika Anda dapat menekan dua tombol lainnya. Saya masih menunjukkan pesan itu. Jadi mungkin mereka menggunakan beberapa API pribadi dan entah bagaimana berhasil dimasukkan ke appstore.
iDev
2
Tidak lagi dimungkinkan pada iOS 7.
God of Biscuits
1

Swift 4+

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

dengan menggunakan pengamat ini Anda bisa mengetahui kapan pengguna mengambil tangkapan layar, tetapi Anda tidak bisa mencegahnya.

Hamid Shahsavari
sumber
0

Swift 4 Contoh

Contoh # 1 menggunakan penutupan

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

Contoh # 2 dengan pemilih

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

@objc func screenshotTaken() {
    print("Screenshot taken!")
}
Devbot10
sumber