iOS에서 프로그래밍 방식으로 스크린샷 찍기
iOS는 앱 내부에서 프로그래밍 방식으로 화면을 캡처하는 공식 API를 제공하지 않습니다. 대신 사용자가 홈 버튼과 전원 버튼을 동시에 눌러 직접 스크린샷을 찍는 기능만 기본으로 제공합니다.
하지만 UIKit의 그래픽 컨텍스트를 활용하면 현재 화면을 이미지로 렌더링한 뒤 사진 앨범에 저장하는 방식으로, 사실상 프로그래밍 방식의 스크린샷을 구현할 수 있습니다. 이 과정은 다음과 같은 단계로 진행됩니다.
구현 단계
- keyWindow의 레이어(layer)를 가져옵니다 –
UIApplication.shared.keyWindow!.layer - 화면의 스케일(scale) 값을 가져옵니다 –
UIScreen.main.scale - 뷰와 동일한 크기의 새로운 이미지 컨텍스트를 생성합니다.
- 레이어를 컨텍스트에 렌더링한 후 이미지로 변환하여 저장합니다.
프로젝트 설정 및 코드 작성
먼저 새로운 Xcode 프로젝트를 생성합니다. 메인 뷰 컨트롤러에 배경색을 지정하고, 버튼 하나를 드래그해 추가한 뒤 해당 클래스에 액션(action)으로 연결합니다. 그다음 액션 메서드에 아래 코드를 작성합니다.
@IBAction func takeshot(_ sender: Any) {
var image :UIImage?
let currentLayer = UIApplication.shared.keyWindow!.layer
let currentScale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(currentLayer.frame.size, false, currentScale);
guard let currentContext = UIGraphicsGetCurrentContext() else {return}
currentLayer.render(in: currentContext)
image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let img = image else { return }
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil)
}권한 설정 및 주의사항
앱을 처음 실행해 이 기능을 사용할 때는 이미지를 저장하기 위해 사진 라이브러리 접근 권한을 허용해야 합니다. 저장된 이미지는 .jpg 형식으로 사진 앱에 추가됩니다.
또한 앱의 info.plist 파일에 반드시 “NSPhotoLibraryAddUsageDescription” 키를 추가해야 합니다. 이 키에는 사용자에게 사진 앨범 접근 권한을 요청하는 이유를 설명하는 문구를 입력합니다. 이 값이 없으면 앱이 크래시될 수 있으니 주의하세요.
참고: iOS 13부터UIApplication.shared.keyWindow는 deprecated(지원 중단 예정) 상태입니다. 최신 iOS 버전을 대상으로 한다면UIApplication.shared.connectedScenes를 통해 현재 활성화된 windowScene의 keyWindow를 가져오는 방식으로 코드를 수정하는 것이 좋습니다.
재사용 가능한 형태로 만들기
위 코드는 함수나 UIView 확장(extension) 형태로 변환하면 여러 곳에서 손쉽게 재사용할 수 있습니다. 예를 들어 특정 뷰만 캡처하고 싶다면 keyWindow 대신 해당 뷰의 layer를 렌더링하면 됩니다.
실행 결과 확인
앱을 빌드하고 실행하면 다음과 같은 화면이 나타납니다.

앱을 처음 실행한 뒤 “take shot” 버튼을 클릭하면 아래와 같이 사진 라이브러리 접근 권한 요청 알림이 표시됩니다.

접근 권한을 허용한 후 iPhone의 사진 앱을 열면 캡처된 이미지가 정상적으로 저장되어 있는 것을 확인할 수 있습니다.
