MIME 타입은 iOS에서 네트워크, 파일 시스템 및 프로세스 간 통신을 통해 전송할 때 파일 타입을 결정하는 데 사용되는 표준화된 데이터 형식 식별자입니다. Apple 개발자 문서, 2024에 따르면 MIME 타입(Multipurpose Internet Mail Extensions)은 파일을 내용에 따라 분류합니다: image/jpeg, application/pdf, text/plain. iOS는 시스템 파일 처리를 위해 UTType을 통해 MIME을 UTI(유니폼 타입 식별자)로 변환합니다.
핵심 사항
MIME 타입(Multipurpose Internet Mail Extensions)은 메인 타입(type)과 서브타입(subtype)의 두 부분으로 구성되며 슬래시로 구분되는 표준화된 데이터 형식 식별자입니다. 주요 카테고리: text(텍스트), image(이미지), audio(오디오), video(비디오), application(바이너리 데이터), multipart(복합 메시지).
MIME 표준은 원래 이메일 첨부 파일용으로 개발되었지만(RFC 2046, 1996), 오늘날에는 모든 곳에서 사용됩니다: HTTP 서버는 응답의 Content-Type을 지정하고, 브라우저는 파일 처리 방법을 결정하며, 모바일 애플리케이션은 열 수 있는 데이터를 식별합니다. IANA(Internet Assigned Numbers Authority)는 등록된 MIME 타입의 레지스트리를 관리합니다.
IANA 미디어 타입 레지스트리(2024)에 따르면 1800개 이상의 공식 MIME 타입이 등록되어 있으며, 사용자 정의 및 벤더 타입을 포함한 실제 수는 5000개를 초과합니다. iOS는 대부분의 표준 타입을 지원하며 유니폼 타입 식별자를 통해 이를 처리하는 API를 제공합니다.
UTI(유니폼 타입 식별자)는 iOS 및 macOS 내에서 사용되는 Apple 자체 콘텐츠 타입 식별 시스템입니다. MIME과 달리 UTI는 상속 계층을 지원하며(예: public.image는 public.png와 public.jpeg의 부모), 파일 형식뿐만 아니라 추상 데이터 타입도 포함합니다.
| MIME 타입 | UTI | 확장자 | 설명 |
|---|---|---|---|
| image/jpeg | public.jpeg | .jpg, .jpeg | JPEG 이미지 |
| application/pdf | com.adobe.pdf | PDF 문서 | |
| text/plain | public.plain-text | .txt | 텍스트 파일 |
| application/json | public.json | .json | JSON 데이터 |
| video/mp4 | public.mpeg-4 | .mp4 | MP4 비디오 |
변환 iOS에서 MIME과 UTI 간의 변환은 UTType 클래스(iOS 14+)를 통해 수행됩니다. 시스템은 대부분의 표준 형식을涵盖하는 내부 매핑 데이터베이스를 유지합니다. 사용자 정의 타입의 경우 개발자가 Info.plist에 매핑을 등록합니다.
import UniformTypeIdentifiers
let mimeType = "image/jpeg"
if let uti = UTType(mimeType: mimeType) {
print("UTI: \(uti.identifier)")
print("이미지에 부합: \(uti.conforms(to: .image))")
print("확장자: \(uti.preferredFilenameExtension ?? "")")
}
// 역변환: UTI에서 MIME으로
if let uti = UTType(filenameExtension: "pdf"),
let mime = uti.preferredMIMEType {
print("PDF용 MIME: \(mime)")
}
UTI 계층을 통해 타입이 특정 카테고리에 부합하는지 확인할 수 있습니다. 예를 들어, 모든 이미지 타입(JPEG, PNG, GIF)은 conform(to: .image)합니다. 이는 그룹 필터링 및 타입이 시스템 구성 요소에서 처리 가능한지 확인하는 데 유용합니다.
중요한 차이점: MIME은 평면 분류(상속 없음)인 반면, UTI는 다중 상속을 지원합니다. 예를 들어, public.html은 public.source-code와 public.text 모두에 부합합니다. 이는 iOS에서 파일을 처리할 때 더 유연한 라우팅을 제공합니다.
세 가지 방법으로 iOS에서 MIME 타입을 확인할 수 있습니다: 파일 확장자로(빠르지만 신뢰성 낮음), 매직 바이트를 통한 내용으로(신뢰성 높지만 파일 읽기 필요), HTTP Content-Type 헤더로(네트워크 요청 전용).
import UniformTypeIdentifiers
enum MIMEDetector {
// 확장자로 감지
static func fromExtension(_ ext: String) -> String? {
UTType(filenameExtension: ext)?.preferredMIMEType
}
// 내용으로 감지(매직 바이트)
static func fromFile(at url: URL) -> String? {
guard let handle = try? FileHandle(forReadingFrom: url) else {
return nil
}
defer { handle.closeFile() }
let header = handle.readData(ofLength: 12)
// PNG: 89 50 4E 47 0D 0A 1A 0A
// JPEG: FF D8 FF
// PDF: 25 50 44 46
// ZIP: 50 4B 03 04
if header.starts(with: [0x89, 0x50, 0x4E, 0x47]) {
return "image/png"
}
if header.starts(with: [0xFF, 0xD8, 0xFF]) {
return "image/jpeg"
}
if header.starts(with: [0x25, 0x50, 0x44, 0x46]) {
return "application/pdf"
}
return nil
}
}
확장자 기반 확인은 UTType을 통한 가장 빠른 방법이지만, 확장자가 없거나 위조된 경우 신뢰할 수 없습니다. 공격자는 .exe를 .jpg로 이름을 바꿀 수 있으며 — 시스템은 파일이 실행 가능하더라도 image/jpeg로 식별합니다. 중요한 시나리오(보안, 의료 데이터)에서는 항상 내용 기반 검증을 사용하세요.
매직 바이트는 각 형식에 고유한 파일의 첫 번째 바이트입니다. 대부분의 형식에는 2~12바이트의 시그니처가 있습니다. iOS는 내용에 의한 내장 MIME 감지기를 제공하지 않습니다 — 개발자가 직접 시그니처 테이블을 구현하거나 CocoaLumberjack 같은 라이브러리 또는 휴리스틱 기반 사용자 정의 감지기를 사용합니다.
사용자 정의 타입은 애플리케이션이 IANA나 Apple에 등록되지 않은 독점 데이터 형식으로 작업할 때 필요합니다. Info.plist에 등록하면 iOS가 이러한 파일을 올바르게 처리할 수 있습니다: Files.app에서 열기, 아이콘 표시, UIActivityViewController를 통해 다른 애플리케이션으로 전달.
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>MyApp Document</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.myapp.secret-doc</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.myapp.secret-doc</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array><string>sdoc</string></array>
<key>public.mime-type</key>
<array><string>application/vnd.myapp.secret-doc</string></array>
</dict>
</dict>
</array>
사용자 정의 타입을 등록하려면 Info.plist에 다음을 지정해야 합니다: UTI 식별자(reverse-DNS 형식), 부모 타입에 대한 부합, 파일 확장자, MIME 타입. iOS는 파일 라우팅에 이 정보를 사용합니다: 사용자가 .sdoc 파일을 열면 시스템은 해당 소유자가 사용자의 애플리케이션임을 알 수 있습니다.
UTExportedTypeDeclarations — 애플리케이션이 정의하는 타입용(내보내기). UTImportedTypeDeclarations — 다른 애플리케이션이 생성했지만 앱이 작업할 수 있는 타입용(가져오기). Apple은 올바른 시스템 통합을 위해 애플리케이션이 작업하는 모든 사용자 정의 타입을 등록할 것을 권장합니다.
알 수 없는 MIME 타입은 iOS 애플리케이션에 보안 위험을 초래합니다. 파일의 타입이 알 수 없거나 확인되지 않은 경우, 애플리케이션은 주의를 기울여야 합니다: 파일을 자동으로 열지 말고, 사용자에게 경고를 표시하며, 처리 전에 내용을 분석합니다.
주요 위협: 위조된 MIME 타입의 파일에는 악성 코드나 파서 취약점을 노린 익스플로잇이 포함될 수 있습니다. iOS는 샌드박스를 통해 시스템을 보호하지만, 애플리케이션이 내용을 확인하지 않고 MIME 타입을 신뢰하면 취약해질 수 있습니다. 신뢰할 수 없는 출처의 파일은 항상 매직 바이트로 확인하세요.
OWASP 모바일 보안 가이드(2024)에 따르면 알 수 없는 타입의 파일을 처리할 때 다음 관행이 적용됩니다: 신뢰할 수 없는 출처의 application/octet-stream MIME 타입 파일을 거부합니다; UTType을 사용하여 예상 카테고리에 대한 부합을 확인합니다; 사용자 확인 없이 외부 애플리케이션에서 파일을 열지 않습니다; 보안 감사를 위해 MIME과 실제 내용 불일치 사례를 모두 기록합니다.
사용자 정의 MIME 타입을 Info.plist에 등록하는 것은 기능뿐만 아니라 보안입니다. 애플리케이션이 자신의 타입만 올바르게 등록하면 시스템이 실수로 다른 파일을 전달하지 않습니다. 다른 애플리케이션과의 충돌을 피하기 위해 일반 접두사(application/x-format) 대신 특정 벤더 접두사(application/vnd.company.app-format)를 사용하세요.
자주 묻는 질문
MIME 타입은 타입과 서브타입(예: image/jpeg)으로 구성된 표준 데이터 형식 식별자입니다. HTTP 서버, 브라우저 및 애플리케이션에서 파일 처리 방법을 결정하는 데 사용됩니다.
UTI(유니폼 타입 식별자)는 상속 계층을 지원하는 Apple의 콘텐츠 타입 식별 시스템입니다. MIME은 네트워크용 평면 표준입니다. iOS는 preferredMIMEType 속성을 통해 UTI와 MIME 간 변환에 UTType을 사용합니다.
세 가지 방법: 확장자로 UTType(filenameExtension:)을 통해, 내용으로 매직 바이트를 통해(파일의 첫 바이트), HTTP 헤더로 Content-Type. 보안을 위해 확장자만이 아닌 내용 기반 검증을 사용하세요.
Info.plist에 UTExportedTypeDeclarations를 추가: UTI 식별자(com.company.format), 파일 확장자, MIME 타입 및 부모 타입을 지정합니다. 이 확장자의 파일은 자동으로 애플리케이션에 연결됩니다.
알 수 없는 MIME을 신뢰하지 마세요. 매직 바이트로 내용을 확인하고, 사용자에게 경고를 표시하며, 파일을 자동으로 열지 마세요. application/octet-stream 타입의 파일은 처리 전에 항상 휴리스틱 분석을 수행하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.