Source#
Apple Developer Forums: https://developer.apple.com/forums/thread/845188
Problem#
An HLS asset exposes one EC-3 audio rendition and multiple WebVTT subtitle renditions. The app loads asset.load(.allMediaSelections), assigns those selections to AVAssetDownloadConfiguration.primaryContentConfiguration.mediaSelections, and creates the task with makeAssetDownloadTask(downloadConfiguration:).
On iOS 17+, the expected supplemental audio/subtitle data is downloaded. On iOS 16 physical devices, the same configuration can finish with an incomplete .movpkg: some supplemental stream directories are absent, while others contain only StreamInfoBoot.xml / StreamInfoRoot.xml and no media fragments. Offline playback later falls back to the network and fails with NSURLErrorDomain -1009.
The sample master playlist also uses FairPlay via EXT-X-SESSION-KEY, so the final package must satisfy both media-selection and persisted-key requirements; however, the reported missing directories/fragments are first a media-download completeness problem, not proof of a FairPlay key failure.
Evidence level#
Recent Apple Developer Forums report + public AVFoundation download contract. Root cause inside iOS 16 remains unconfirmed.
Apple documents that AVAssetDownloadContentConfiguration.mediaSelections specifies the media selections a task downloads. Apple’s HLS-variant guidance also shows multiple audio/subtitle media selections on the primary content configuration, with auxiliary configurations intended for additional content/variant families. Therefore, if requested media selections are accepted by the task but their fragments are absent only on iOS 16 while the same configuration works on newer releases, treat this as an OS-specific download-path defect/limitation until disproven.
Public API model#
AVURLAsset
→ AVAssetDownloadConfiguration
→ primaryContentConfiguration
├─ variantQualifiers
└─ mediaSelections
→ auxiliaryContentConfigurations (optional additional content families)
→ AVAssetDownloadTask
→ .movpkg
→ AVAssetCache inspection
→ offline playback
primaryContentConfiguration.mediaSelections is not just a preference for playback; it is part of the download configuration. AVAssetCache.mediaSelectionOptions(in:) is the authoritative post-download check for which options are actually available offline.
Important distinction#
Do not collapse these states:
download task completed
≠
all requested media selections persisted
≠
asset is playable offline with every advertised language
≠
FairPlay persisted keys exist for every protected stream
A completed task can still leave the product requirement unsatisfied if required supplemental selections are missing.
Support / triage answer#
1. Keep primary vs auxiliary semantics straight#
For one principal downloaded presentation, it is valid to put multiple desired AVMediaSelection values into primaryContentConfiguration.mediaSelections. Apple’s WWDC21 HLS-variant example does exactly this for English/French audio and subtitles.
Use auxiliaryContentConfigurations when you need additional content configurations/variant families—for example, a separate multichannel or lossless audio variant—rather than assuming every subtitle must be an auxiliary configuration.
Therefore, simply moving every subtitle into an auxiliary configuration is not a justified fix for this iOS 16-only failure.
2. Verify the result, not only task completion#
After download, recreate AVURLAsset from the local package URL and inspect:
asset.assetCache?.isPlayableOffline
asset.assetCache?.mediaSelectionOptions(in: audibleGroup)
asset.assetCache?.mediaSelectionOptions(in: legibleGroup)
Compare the returned languages/options with the requested set.
If French/Kazakh/Uzbek subtitles were requested but are absent from AVAssetCache, classify the package as incomplete for the product requirement even if the task completed successfully.
3. Build an OS A/B matrix#
Use identical manifest, configuration and device-family where possible:
A. iOS 16 physical device
B. iOS 17 physical device
C. latest supported iOS physical device
For each requested media selection record:
selection identity / locale
forced/default/autoselect state
whether configuration contains it
whether delegate reports progress/completion for it
whether a stream directory exists in .movpkg
whether media fragments exist
whether AVAssetCache exposes it offline
This finds the first divergent state instead of discovering the problem only during playback.
4. Separate subtitle/audio completeness from FairPlay#
The manifest uses EXT-X-SESSION-KEY, but missing supplemental fragment data should be proven independently of key persistence.
Model two parallel requirements:
media package completeness:
media selection → stream materialization → local fragments
content protection:
key identifier → persistable key → offline decrypt
Only enter FairPlay debugging after the requested rendition is physically present and offline playback still fails at key/decryption.
5. Treat iOS 16 Simulator separately#
The forum report also sees NSURLErrorDomain -16090 for asset downloads on the iOS 16 Simulator while newer simulators work. Do not use that simulator failure as evidence for the physical-device supplemental-track bug; they are distinct observations until a shared implementation cause is demonstrated. Validate offline-download behavior primarily on physical devices.
Verification matrix#
iOS 16 iOS 17+
primary audio ? ?
non-default audio ? ?
normal subtitle ? ?
forced subtitle ? ?
.movpkg fragments ? ?
AVAssetCache options ? ?
offline playback ? ?
Also test configuration shape independently:
A. one primary media selection
B. primary + one subtitle
C. primary + all subtitles
D. primary + alternate audio
E. primary config + deliberate auxiliary content config
The goal is to determine whether iOS 16 fails because of a specific media characteristic, selection count/combination, variant relationship, or generic supplemental-download scheduling.
Client mitigation#
Until the iOS 16 internal cause is established:
- Treat download completion as provisional.
- Verify required offline options with
AVAssetCachebefore declaring the title fully downloaded. - If required tracks are absent, mark the download incomplete and avoid promising those selections offline.
- For products that must still support iOS 16, test the older aggregate/additional-media-selection download path as a controlled compatibility experiment, because it was the historical API for multiple media selections; do not present it as a guaranteed fix without device evidence.
- Keep persisted FairPlay-key verification separate from media-fragment completeness.
- File Feedback with one minimal manifest, exact requested media-selection identities, resulting
.movpkginventory, and an iOS 16 vs iOS 17 comparison.
Reusable engineering rule#
Offline download correctness is a set-membership problem: the package is complete only if the set of locally cached media selections contains every selection the product promised to the user.
Use:
requested selections
→ accepted download configuration
→ per-selection download execution
→ local package materialization
→ AVAssetCache-visible selections
→ offline playback
The first missing member is the useful root-cause boundary.
References#
- Apple Developer Forums: https://developer.apple.com/forums/thread/845188
AVAssetDownloadConfiguration: https://developer.apple.com/documentation/avfoundation/avassetdownloadconfigurationAVAssetDownloadContentConfiguration.mediaSelections: https://developer.apple.com/documentation/avfoundation/avassetdownloadcontentconfiguration/mediaselectionsAVAssetCache: https://developer.apple.com/documentation/avfoundation/avassetcache- WWDC21 — Explore HLS variants in AVFoundation: https://developer.apple.com/videos/play/wwdc2021/10143/
- WWDC20 — Discover how to download and play HLS offline: https://developer.apple.com/videos/play/wwdc2020/10655/