안녕하세요. 리안입니다.
제가 만든 앱 중에 얼굴을 이모지로 가리거나 블러/모자이크 처리해주는 앱이 있습니다.
(https://apps.apple.com/app/id1624326541)
이 앱이 얼굴을 가리고 나서 이걸 이미지로 저장하려면 광고를 봐야 저장이 되는 수익 구조를 가지고 있습니다.
(광고 제거 상품 구입을 유도하기 위한 쉐어웨어 같은 개념으로 만든...)
프리뷰 상태에서 얼굴을 가리고... 이걸 캡쳐해서 쓸 수도 있겠다고 생각해서
통계를 달아놨는데... 역시나 생각보다 적지 않은 비율로 캡쳐를 하고 있더라구요.
그래서 이번 기회에 화면 캡쳐를 막기 위한 삽질들을 좀 해봤습니다.
1. 화면 녹화 / 화면 캡쳐
- 화면 녹화는 UIScreen.main.isCaptured 으로 현재 녹화 중인지 확인이 가능하고,
녹화 시작 / 종료 시점은 NotificationCenter 의 UIScreen.capturedDidChangeNotification 메시지를 통해 확인이 가능합니다.
- 화면 캡쳐는 캡쳐 시작 시점은 알 수 없고,
NotificationCenter 의 UIApplication.userDidTakeScreenshotNotification 메시지로 캡쳐가 이뤄진 이후에 체크가 가능합니다.
이걸 이용해 사용자들이 캡쳐를 하고 있던건 로그를 남겨서 확인하고 있었습니다.
즉, 화면 캡쳐의 경우에 user 'Will' TakeScreenshotNotification 을 보내주지 않기 때문에 막을 수가 없었습니다.
애플이 다 뜻이 있었겠지만 왜 will 은 제공안하고 did만 제공하는지는 잘 모르겠네요 -_-);
2. 검색...
검색을 해보니 UITextField 의 isSecureTextEntry 필드를 활용한 꼼수가 있더라구요.
(https://developer.apple.com/documentation/uikit/uitextinputtraits/1624427-issecuretextentry)
원래 UITextField의 isSecureTextEntry 속성은...
민감한 개인정보 - 주민등록번호나 전화 번호 같은걸 입력한 상태에서 화면 캡쳐를 할 경우 이 필드는 캡쳐가 되지 않게
시스템적으로 보안 처리하기 위해 만들어진 필드였습니다. (iOS 2.0 부터 있었던것도 놀랍네요;)
암튼... 이걸 활용하면 캡쳐를 막을 수 있더라구요.
3. 원리
UITextField 에 isSecureTextEntry 를 true로 해놓으면 캡쳐가 안되니까...
UITextField 의 하위 layer 에 내가 원하던 컨텐츠 레이어랑 스왑을 하면 됩니다.
내가 보여줄 뷰가 A 라는 뷰라면... A 라는 뷰는 어떤 뷰컨트롤러에 붙어있겠죠?
A라는 뷰를 뷰컨트롤러에서 떼내고, UITextField 를 A 가 붙어있던 뷰컨트롤러에 붙인다음,
UITextField 하위 레이어에 A 를 다시 붙이면 끝.
사용자가 캡쳐를 하면 UITextField 가 캡쳐가 안되니까... A도 같이 감춰지는 형태입니다. ㅎㅎ;
추가적으로 사용자가 캡쳐했을 때 경고 같은걸 해준다고 하면 1. 에서 찾아낸 캡쳐/녹화 타이밍에 얼럿 같은걸 띄워주면 되죠.
생각보다 간단했습니다.
4. 구현...
이런 저런 삽질로 Swiftui 에 간단히 구현했네요. (굳이 소스를 남길 필요는 없을거 같... 이유는 아래에)
암튼 다 구현하고 나서 github 검색해봤더니.
짜잔.
https://github.com/igooor-bb/GreedyKit
https://github.com/yoxisem544/ScreenshotPreventing-iOS
누군가 이미 잘 구현해놓은게 있네요.
이걸 왜 이제 봤지 싶었는데 제가 앱 처음 개발할 때가 작년인데, 그 사이에 배포 된 라이브러리더라구요. -_-);
누군가 이 트릭을 찾은게 생각보다 오래되진 않았던거 같기도 하네요.
ㅠ
iOS 에서 캡쳐 / 녹화를 막고 싶다면 도움이 되셨길 바랍니다.
감사합니다.
끝.!
수정) 다시 보니 캡쳐를 막은게 아니라 캡쳐시 신분증 정보들이 나오지 않게 처리 했던 거였네요?!
/Vollago
따라서 작성자분의 사례 정도는 괜찮을 것 같긴 한데,, 위 방법도 과하게 사용할 경우 심사 리젝 가능성이 있지 않을까 생각이 드네요
여튼 재밌는 글 잘 봤습니다ㅎㅎㅎ
정보 감사합니다.
기억해두었다가 언젠가 써먹겠습니다. 좋은 후기(?) 공유해주셔서 고맙습니다.
최근에 swiftui 만 하던터라 uiview 하위 layer 에 끼워넣는거 보고 감탄했네요. ㅎㅎ