-
Swift iOS: 이미지를 불러오는 Action Extension(액션 확장)에서 스크린샷 이미지를 인식하지 못하는 문제 해결 방법공부/Swift(프로그래밍 언어) 2026. 2. 8. 19:29반응형
문제
- 이미지를 불러오는 Action Extension 코드가 있음
- 다른 경우는 전부 이미지를 불러올 수 있는데 특정 케이스에서는 이미지를 불러오지 못함
- 예) 스크린샷 직후 공유 메뉴를 실행했을 때

기존 코드
import UIKit import SwiftUI import MobileCoreServices import UniformTypeIdentifiers class ActionViewController: UIViewController { // ... // private func handleInputImage() { guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } guard let attachments = extensionItem.attachments else { return } for provider in attachments { if provider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { provider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { item, error in if let error { print("이미지 로드 오류:", error) return } var image: UIImage? if let url = item as? URL { if let data = try? Data(contentsOf: url) { image = UIImage(data: data) } } else if let uiImage = item as? UIImage { image = uiImage } DispatchQueue.main.async { // self.showSwiftUI(with: image) let red = UIView() red.backgroundColor = .red self.view.addSubview(red) if let image { self.saveImageToAppGroup(image) } } } } } } // ... // }해결 방법
스크린샷으로 찍은 저장 전 화면이 Action Extension에서 안 읽히는 이유는, 이 경우 이미지가 파일(URL)이나 UIImage가 아니라 in-memory PNG/JPEG Data 형태로 전달되는 경우가 많기 때문입니다.
핵심 원인
- 사진 앱에 저장된 이미지 → URL 또는 UIImage로 전달되는 경우가 많음
- 스크린샷 직후 공유(저장 전) → UTType.image는 매칭되지만 실제 item은 Data (PNG/JPEG) 형태로 전달되는 경우가 있음
- 기존 코드에서는 URL, UIImage만 처리 → 스크린샷 누락
변경 코드
private func handleInputImage() { guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } guard let attachments = extensionItem.attachments else { return } for provider in attachments { if provider.hasItemConformingToTypeIdentifier(UTType.image.identifier) { provider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { item, error in if let error { print("이미지 로드 오류:", error) return } var image: UIImage? var message: String = "이미지 로드 실패" if let url = item as? URL { if let data = try? Data(contentsOf: url), let loadedImage = UIImage(data: data) { image = loadedImage message = "URL 기반 이미지 로드" } else { message = "URL은 있으나 이미지 데이터 변환 실패" } } else if let uiImage = item as? UIImage { image = uiImage message = "UIImage 형태로 로드" // ⬇️⬇️⬇️ item이 데이터인 경우 추가 } else if let data = item as? Data, let loadedImage = UIImage(data: data) { image = loadedImage message = "Data 형태로 로드 (스크린샷 가능)" } DispatchQueue.main.async { self.showSwiftUI(with: image, message: message) } } // ⬇️⬇️⬇️ PNG 메모리 데이터 부분 추가 } else if provider.hasItemConformingToTypeIdentifier(UTType.png.identifier) { provider.loadDataRepresentation(forTypeIdentifier: UTType.png.identifier) { data, error in if let data, let image = UIImage(data: data) { DispatchQueue.main.async { self.showSwiftUI(with: image, message: "PNG Data로 스크린샷 로드") } } } } } }적용한 해결 방식 (패치 내용 요약)
- item as? Data 처리 추가
- UIImage(data:)로 변환
- 스크린샷 Data 케이스 대응
- UTType.png에 대한 별도 분기
- loadItem 대신 loadDataRepresentation(forTypeIdentifier:) 사용
- 저장 전 스크린샷에서 가장 안정적인 방식
이렇게 하면 대부분의 케이스가 모두 커버됩니다.
왜 loadDataRepresentation이 중요한가
- Action Extension은 다른 앱의 메모리 버퍼를 직접 받는 구조
- 스크린샷은 아직 파일 시스템에 없을 수 있음
- 이 경우 URL이 아예 존재하지 않음
- Apple도 이미지 공유 확장에서는 Data 기반 처리를 권장하는 편입니다
실무 팁
- 이미지 공유 Extension에서는
- URL
- UIImage
- Data
세 가지를 항상 모두 처리하는 것이 안전합니다.
추가로:
- HEIC (UTType.heic)
- JPEG (UTType.jpeg)
까지 커버하고 싶으시면 동일 패턴으로 확장 가능합니다.
반응형'공부 > Swift(프로그래밍 언어)' 카테고리의 다른 글
SwiftUI TCA: Alert (경고창) 만드는 방법 (0) 2026.02.05 SwiftUI: 탭바가 있는 뷰(TabView) 만들기 (구버전, 신버전) (0) 2026.02.04 SwiftUI TCA: 내비게이션 페이지 이동 (패스, 스택) (0) 2026.01.31 SwiftUI: ‘appendInterpolation’ is deprecated 문제 해결하기 (0) 2026.01.28 Xcode Swift UIKit 프로젝트 스토리보드 없이 만드는 법 (0) 2026.01.24