iOSでスクリーンショットを制限する方法について
結論
- iOSでスクリーンショット禁止は今のところ可能(iOS17時点)
- ただ、アップデートで使えなくなる可能性がある
- ストア審査でリジェクトされる可能性がある
- なので、iOSでスクショ禁止は対応しない方が良いかも
なんでスクショ禁止にしたいか?
- クーポンコードなどをスクショして悪用するケースを防ぎたい
- 著作権を守るため(ex.漫画、映画など)
スクショを禁止にする方法
- DRM(Digital Rights Management)を使用する
- Appleに依頼が必要(割愛)
- 参考記事
- UITextFieldの.isSecureTextEntryプロパティを活用する
- 今回はここ
スクショ防止ではないけど…
- NotificationCenterの下2つを活用する
- userDidTakeScreenshotNotification (スクリーンショット)
- capturedDidChangeNotification (スクリーンレコーディング)
NotificationCenterでダメな理由
- userDidTakeScreenshotNotificationとcapturedDidChangeNotificationなので、スクショ(レコーディング)撮られた後に呼ばれる
- レコーディングはある程度防げそうだが、スクショは不可
UITextFieldの.isSecureTextEntryでスクショを防ぐ方法
- UITextFieldの.isSecureTextEntryプロパティをtrueにすると入力中の情報が録画されない
- UITextFieldのSubViewの一つ、UITextLayoutCanvasViewが画面録画を回避するUIViewになっているのでこの子でカスタムビューを作成し、その中に撮られたくないViewを入れる
SecureField(カスタムTextField)
class SecureField : UITextField {
override init(frame: CGRect) {
super.init(frame: .zero)
self.isSecureTextEntry = true
self.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
weak var secureContainer: UIView? {
let secureView = self.subviews.filter({ subview in
type(of: subview).description().contains("CanvasView")
}).first
secureView?.translatesAutoresizingMaskIntoConstraints = false
secureView?.isUserInteractionEnabled = true //To enable child view's userInteraction in iOS 13
return secureView
}
override var canBecomeFirstResponder: Bool {false}
override func becomeFirstResponder() -> Bool {false}
}
ViewController
private func setupSecurePhoto() {
imageView.image = UIImage(named: "kawa_taki")
imageView.contentMode = .scaleAspectFit
guard let secureView = SecureField().secureContainer else {
return
}
secureView.addSubview(imageView)
imageView.pinEdges()
photoContainerView.addSubview(secureView)
secureView.pinEdges()
}
数年前は他にも方法があった(今は使えない)
- UIViewのextensionにisSecureTextEntryをtrueにしたUITextFieldをaddSubViewしてあげる方法
- iOS17で使えなくなった…
- 参考記事
extension UIView {
func makeSecure() {
DispatchQueue.main.async {
let field = UITextField()
field.isSecureTextEntry = true
self.addSubview(field)
field.translatesAutoresizingMaskIntoConstraints = false
field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.layer.superlayer?.addSublayer(field.layer)
field.layer.sublayers?.first?.addSublayer(self.layer)
}
}
}
- 今回の方法もいつか使えなくなる可能性がある
そもそもAppleの対応は?
- DRMとかはあるけど、そもそもiPhoneを外部カメラで録画されたら防げないよね?とのこと
- AppleForlam
他のアプリの対応は?
- Netflix、PrimeVideo、U-NextはDRMを使用してるっぽい
- 漫画アプリなどの静止画コンテンツは警告を出す (スクショ後に)
- アカウント停止や、 法的措置
- スクリーンショットの回数を保存しておいて何回以上でBANとかありそう
まとめ
- スクショ禁止は今はできるけど今後は無理になるかもしれない
- そもそも完全に防ぐのは無理(外部デバイスで撮れる)
- 他のアプリのような対応が正しいのかも(DRMや警告)