0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

iOSでスクリーンショットを制限する方法について

Posted at

iOSでスクリーンショットを制限する方法について

結論

  • iOSでスクリーンショット禁止は今のところ可能(iOS17時点)
  • ただ、アップデートで使えなくなる可能性がある
  • ストア審査でリジェクトされる可能性がある
  • なので、iOSでスクショ禁止は対応しない方が良いかも

なんでスクショ禁止にしたいか?

  • クーポンコードなどをスクショして悪用するケースを防ぎたい
  • 著作権を守るため(ex.漫画、映画など)

スクショを禁止にする方法

  • DRM(Digital Rights Management)を使用する
  • 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してあげる方法
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や警告)

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?