On-Demand Resources는 Apple의 애플리케이션 콘텐츠 지연 로딩 기술입니다. 모든 리소스를 설치 패키지에 포함하는 대신 개발자는 App Store 서버에 호스팅하고 필요에 따라 요청합니다. Apple ODR Guide에 따르면 이는 초기 설치 크기를 줄이고 앱 버전을 업데이트하지 않고도 새 콘텐츠를 추가할 수 있게 합니다.
핵심 요점
On-Demand Resources (ODR)는 iOS, tvOS 및 macOS에 내장된 콘텐츠 관리 시스템입니다. 개발자가 앱 리소스를 필수(설치 패키지에 포함)와 주문형(App Store에 저장되고 필요 시 다운로드)으로 분할할 수 있습니다.
ODR 시스템은 세 가지 주요 엔티티로 작동합니다: 태그, 리소스 패키지, 요청. 태그는 파일 그룹을 묶는 문자열 식별자입니다. 리소스 패키지는 태그와 연결된 데이터 세트입니다. 요청은 패키지 로딩을 시작하는 NSBundleResourceRequest에 대한 프로그래매틱 호출입니다.
리소스 로딩은 여러 단계를 거칩니다: 지정된 태그로 요청 초기화, 로컬 스토리지에서 가용성 확인, 없으면 Apple 서버에서 다운로드, 준비 완료 시 앱에 알림, 사용 후 리소스 해제. 시스템은 캐싱 및 사용되지 않는 리소스 제거를 자동으로 관리합니다.
| 단계 | 시스템 작업 | 실행 시간 |
|---|---|---|
| 초기화 | 태그로 NSBundleResourceRequest 생성 | 즉시 |
| 캐시 확인 | 로컬 스토리지에서 리소스 검색 | 0.1–0.5초 |
| 다운로드 | Apple CDN에서 다운로드 | 크기에 따라 다름 |
| 알림 | 완료 핸들러 또는 대리자 호출 | 즉시 |
| 해제 | 시스템이 제거할 수 있는 리소스로 표시 | iOS 요청 시 |
ODR 메커니즘은 App Store 클라우드 스토리지의 리소스 요청을 관리하는 백그라운드 서비스를 기반으로 합니다. 앱이 태그를 요청하면 시스템은 리소스가 로컬 캐시에 있는지 확인합니다. 없으면 중단된 연결 재개를 지원하는 백그라운드 URL 세션을 통해 다운로드를 시작합니다.
import Foundation
class ResourceManager {
let odrRequest = NSBundleResourceRequest(tags: ["level-3"])
func loadLevel3() {
odrRequest.conditionallyBeginAccessingResources { available in
if available {
self.startLevel3()
} else {
self.odrRequest.beginAccessingResources { error in
guard error == nil else { return }
self.startLevel3()
}
}
}
}
func releaseResources() {
odrRequest.endAccessingResources()
}
}
conditionallyBeginAccessingResources 메서드는 즉시 로딩 없이 캐시에서 리소스 가용성을 확인합니다. 가용성 플래그가 양수이면 앱이 지연 없이 계속됩니다. 리소스가 없으면 beginAccessingResources가 progress 속성을 통해 진행 상황 표시와 함께 다운로드를 시작합니다.
iOS는 현재 앱 활동에 따라 ODR 리소스 로딩 우선순위를 관리합니다. 앱이 포그라운드에 있을 때는 높은 우선순위로 로딩이 수행됩니다. 백그라운드에서는 배터리가 부족할 때 iOS가 로딩을 지연시키거나 일시 중단할 수 있습니다.
ODR 리소스에는 이미지, 비디오, 오디오 파일, 스프라이트, 레벨 데이터 및 앱 실행에 중요하지 않은 기타 파일이 포함될 수 있습니다. 각 리소스는 기능 블록 소속을 결정하는 하나 이상의 태그에 연결됩니다.
Xcode에서 태그는 Target Membership 탭의 Resource Tags 인스펙터를 통해 구성됩니다. 개발자는 프로젝트의 각 파일에 대해 메인 번들에 포함할지 태그로 로드할지 지정합니다. 하나의 파일이 여러 태그에 속할 수 있어 앱의 다른 섹션에서 리소스를 재사용할 수 있습니다.
<!-- Info.plist에서 Resource Tags 구성 예제 -->
<key>NSBundleResourceRequestTags</key>
<dict>
<key>level-3</key>
<array>
<string>levels/level3.scnassets</string>
<string>textures/level3_tex.png</string>
</array>
</dict>
Apple은 리소스가 기기에 남아 있어야 하는 기간에 따라 세 가지 ODR 태그 카테고리를 구분합니다. 초기 설치 태그는 앱과 함께 로드되며 시스템에 의해 절대 삭제되지 않습니다. 프리페치 태그 순서는 설치 직후 백그라운드 사전 로딩 순서를 결정합니다. 주요 태그는 주문형으로 요청되며 스토리지가 부족할 때 iOS에 의해 삭제될 수 있습니다.
카테고리 외에도 각 태그는 다운로드 우선순위를 가질 수 있습니다. 높은 우선순위 태그는 나중에 요청된 경우에도 낮은 우선순위 태그보다 먼저 로드됩니다. 이를 통해 개발자는 콘텐츠 표시 순서를 제어할 수 있습니다: 먼저 메인 화면의 중요한 리소스, 그 다음 앱의 심층 섹션에 대한 추가 자료.
ODR 설정은 Xcode에서 세 단계로 이루어집니다: 태그별 리소스 분류, Info.plist에서 다운로드 매개변수 구성, NSBundleResourceRequest를 통한 프로그래매틱 요청 구현. 대부분의 작업은 빌드 측에서 수행됩니다.
// ODR 상태 확인 및 진행 상황 모니터링
func monitorODRProgress(tag: String) {
let request = NSBundleResourceRequest(tags: [tag])
let observer = request.progress.observe(\.fractionCompleted) { progress, _ in
DispatchQueue.main.async {
let percent = Int(progress.fractionCompleted * 100)
print("ODR: \(percent)% 로드됨")
}
}
}
다운로드 진행 상황은 KVO 관찰을 지원하는 NSProgress 클래스의 progress 속성을 통해 추적됩니다. 앱은 리소스 다운로드 중에 사용자에게 로딩 표시기를 표시할 수 있습니다. 다운로드 완료 후 리소스는 표준 FileManager 및 NSDataAsset 메커니즘을 통해 메인 앱 번들에서 사용할 수 있습니다.
ODR 할당량은 iOS 버전에 따라 다릅니다. iOS 13부터 기기는 계정당 최대 20GB의 주문형 리소스를 저장할 수 있습니다. 이 공간은 기기에 설치된 모든 앱 간에 공유됩니다 — 한 앱이 많은 공간을 차지하면 다른 앱에 남는 공간이 줄어듭니다.
사용 공간 모니터링은 NSBundleResourceRequest를 통해 수행됩니다. 앱은 사용 가능한 ODR 스토리지를 확인하고 이에 따라 어떤 리소스를 먼저 로드할지 결정할 수 있습니다. 폴백 메커니즘을 구현하는 것이 좋습니다: ODR 스토리지가 가득 찬 경우 메인 번들에서 품질이 낮은 리소스를 사용합니다.
할당량을 초과하면 시스템은 가장 오래된 것부터 가장 최근에 사용되지 않은 순서로 주문형 태그 리소스를 제거합니다. 앱 코드의 리소스 관리자는 NSBundleResourceRequest 속성을 통해 현재 ODR 스토리지 사용량을 추적할 수 있습니다.개발자는 iOS가 언제든지 주문형 리소스를 삭제하기로 결정할 수 있다는 점을 고려해야 합니다 — 앱은 이전에 로드된 리소스가 갑자기 사용 불가능해지는 상황을 올바르게 처리해야 합니다. 리소스 액세스 오류를 가로채고 beginAccessingResources를 통해 다시 요청하는 것이 좋습니다. 앱이 작동하는 데 필수적인 중요 리소스의 경우 시스템에 의해 제거되지 않는 초기 설치 태그를 사용하십시오.
On-Demand Resources는 개발자에게 앱 크기 관리를 위한 유연한 도구를 제공하지만 네트워크 가용성 및 iOS 스토리지 정책과 관련된 여러 제한 사항이 있습니다.
ODR의 주요 장점은 초기 설치 크기의 획기적인 감소입니다. 여러 레벨의 게임, 비디오 콘텐츠가 있는 앱 또는 대규모 이미지 세트는 콘텐츠를 부분적으로 로드할 수 있습니다. 사용자는 즉시 기본 기능에 액세스할 수 있고 추가 리소스는 백그라운드에서 다운로드됩니다.
ODR은 첫 액세스 시 리소스를 로드하기 위해 지속적인 인터넷 연결이 필요합니다. 커버리지가 좋지 않은 지역의 사용자는 지연 및 다운로드 오류가 발생할 수 있습니다. 또한 Apple은 다운로드된 리소스가 기기에 남아 있음을 보장하지 않습니다 — 스토리지가 부족하면 iOS가 경고 없이 주문형 태그를 삭제할 수 있습니다.
자주 묻는 질문
ODR을 사용하면 App Store에 새 버전을 게시하지 않고도 리소스를 추가하고 수정할 수 있습니다. Xcode를 통해 Apple 서버의 파일을 업데이트하고 동일한 태그에 할당하기만 하면 됩니다. 다음 요청 시 앱은 리소스의 최신 버전을 받습니다. 이는 계절별 콘텐츠, 임시 프로모션 및 새 이미지와 레이아웃의 A/B 테스트에 편리합니다.
시스템은 다른 앱을 위한 공간을 확보해야 할 때 주문형 태그 리소스를 삭제합니다. 초기 설치 태그 리소스는 삭제되지 않습니다. 삭제 순서는 LRU(Least Recently Used) 알고리즘에 의해 결정됩니다 — 가장 오랫동안 액세스되지 않은 리소스가 먼저 삭제됩니다.
iOS 13부터 총 ODR 스토리지 제한은 Apple ID 사용자당 20GB입니다. 최적의 다운로드 성능을 위해 단일 태그 크기는 512MB를 초과하지 않아야 합니다. 제한을 초과하면 요청이 NSBundleResourceRequestLowDiskSpaceError로 실패합니다.
예, 다운로드 후 리소스는 로컬 캐시에 저장되며 인터넷 연결 없이 오프라인 모드에서 사용할 수 있습니다. 문제는 iOS가 스토리지 부족으로 리소스를 삭제했는데 사용자가 네트워크 없이 액세스하려고 할 때만 발생합니다.
ODR은 App Store 인프라와 통합되어 있습니다: 리소스는 Apple CDN에 호스팅되고 캐싱 시스템에 의해 관리되며 개발자가 자체 서버를 설정할 필요가 없습니다. URLSession은 서버 인프라, 버전 관리 및 수동 캐시 관리가 필요합니다. ODR은 또한 연결 중단 시 다운로드 재개를 자동으로 처리합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.