Jiwift

[iOS/Swift] isSecureTextEntry : TextField를 사용한 스크린 캡처 방지, 화면 스크린샷 막는 방법, 녹화 방지 본문

iOS Dev/iOS

[iOS/Swift] isSecureTextEntry : TextField를 사용한 스크린 캡처 방지, 화면 스크린샷 막는 방법, 녹화 방지

지위프트 2023. 7. 2. 01:00
반응형

 앱에서 특정 사용자에게만 제공되는 정보가 있다거나, 유료 컨텐츠를 제공해야하는 상황에서 화면이 캡처되는 것은 서비스하는 입장에서 매우 큰 걸림돌입니다. 
 이번 글에서는 화면 캡처와 녹화를 방지하고 다른 화면이 캡처되는 동작까지 수행해보겠습니다. 
 

Apple Document

 Apple은 iOS에서 화면 녹화, 화면 캡처를 공식적으로 만는 방법을 제공하지 않습니다. 하지만 TextField에 있는 isSecureTextEntry를 통해서 이 기능을 구현할 수 있습니다. 
 

extension UIView {
    func preventCapture() {
        DispatchQueue.main.async {
            let textField = UITextField()
            textField.isSecureTextEntry = true

            self.addSubview(textField)
            textField.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
            textField.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true

            textField.layer.removeFromSuperlayer()
            self.layer.superlayer?.insertSublayer(textField.layer, at: 0)
            textField.layer.sublayers?.last?.addSublayer(self.layer)
        }
    }
}

해당 extension을 사용하면 우리가 원하는 View의 화면 캡처와 녹화를 방지할 수 있습니다 .
 

 self.privateView.preventCapture()

extension을 원하는 View에 추가해주면됩니다. 
 
 

좌 : 캡처 방지 / 우 : 녹화 방지

 캡처와 녹화를 잘 막아내는 모습입니다. 화면이 캡처될때 TextField가 적용된 View는 없는 취급 당하며 뒤에 레이어가 표시됩니다. 
 

실행된 레이어

 현재 코드가 적용된 화면의 Layer를 확인한 모습입니다. 신기하게도 캡처를 방지하려는 화면이 복제된 모습입니다. 코드 상에서 레이어를 제거하고 추가하는 과정에서 이런 모습이 나오나봅니다. 
 

새롭게 추가된 View들

  우리는 캡처되는 상황에 뒤 레이어가 보인다는 것을 알았습니다. 그래서 없어진 화면 자리에 다른 표시를 해주기 위해서 위와 같이 Background라는 이름으로 View를 추가해주었고, 실제 어플 처럼 보이기위해 레이어 맨 앞에 View안에 Button을 추가하여 생성했습니다. 
 

실행된 레이어

 새롭게 추가된 View와 위 코드를 적용했을 때 실행된 레이어 모습입니다. 코드를 적용했을 때 숨기고 싶은 화면이 복제되는 모습과 그 사이에 새롭게 추가된 View들이 제대로 추가된 모습을 보여주고 있습니다. 
 

실제 구동된 모습

 하지만 실제 기기에서 테스트했을 경우에는 위에 레이어와는 전혀 다르게 우리가 숨기고 싶은 View가 아예 보이질 않았습니다. 캡처와 녹화하는 상황에만 안보여야하는데 처음부터 보이지가 않습니다. 
 

좌: 노란색 버튼이 눌리는 모습 / 우: 노란색 버튼이 눌리지 않는 모습

 테스트를 더 진행하기 위해서 노란색 화면에 버튼을 추가하여 버튼이 눌리는지 확인한 결과 숨길 예정 화면이 눈에만 보이지 않을 뿐 레이어는 존재하고있었습니다. 
 
 위 실험은 우리가 숨기고 싶은 View를 아예 제거해서 노란색 버튼이 잘 눌리는지 먼저 확인하고, 우리가 숨기고 싶은 View를 다시 추가하고 눌렀을 때 입니다. 오른쪽 GIF를 보시면 버튼을 누르고 있음에도 눈에 보이지 않는 View 레이어가 버튼을 막고있습니다. 
 
 레이어는 정확한 위치에 존재하기 때문에 보이지 않는 문제를 먼저 해결해야했습니다. 

extension UIView {
    func preventCapture() {
        DispatchQueue.main.async {
            let textField = UITextField()
            textField.isSecureTextEntry = true

            self.addSubview(textField)
            textField.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
            textField.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true

            textField.layer.removeFromSuperlayer()
            // 수정된 부분 'at: 0'에서 'at: 1'로 변경
            self.layer.superlayer?.insertSublayer(textField.layer, at: 1)
            textField.layer.sublayers?.last?.addSublayer(self.layer)
        }
    }
}

 생각보다 간단하게 해결되었는데 코드를 위와 같이 수정하였더니 잘 구동되었습니다.
(layer를 0번째가 아닌 1번째로 insert하는 방법으로 수정했습니다. )
 
사용하는 화면에 따라서 여러가지 해결하는 방법이 다를 수 있을 것 같습니다. 
 

최종 결과물

 화면을 캡처했을때와 녹화했을 때 우리가 원하는 화면이 잘 숨겨진 모습을 확인할 수 있습니다. 
 
추가적인 테스트로 숨기고 싶은 화면에 Button을 추가하였는데, 문제 없이 잘 동작하였습니다. 
 
 
 
해당 글은 아래 링크를 참고하여 작성되었습니다. 
[iOS - Swift] 1. Prevent Capture, Recording - 캡쳐 막는 방법, 화면 녹화 방지 (isSecureTextEntry) (tistory.com)

[iOS - Swift] 1. Prevent Capture, Recording - 캡쳐 막는 방법, 화면 녹화 방지 (isSecureTextEntry)

1. Prevent Capture, Recording - 캡쳐 막는 방법, 화면 녹화 방지 (isSecureTextEntry) 2. Prevent Capture, Recording - 캡쳐 감지 방법, 녹화 감지 방법 Capture를 막는 아이디어 안드로이드처럼 사용자가 캡쳐를 했을때

ios-development.tistory.com

 

반응형