2025 App ServicesApp Store, Distribution & MarketingGraphics & GamesSystem Services
WWDC25 · 25 min · App Services / App Store, Distribution & Marketing / Graphics & Games / System Services
Discover Apple-Hosted Background Assets
Building on Background Assets, this session will introduce the new capability to download asset packs of content for games and other applications. Learn how Apple can host these asset packs for you or how to manage self-hosting options. We’ll delve into the native API integration and the corresponding App Store implementations, providing you with the tools to enhance your app’s content delivery and user experience.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 9 snippets
Fill out the manifest
{
"assetPackID": "[Asset-Pack ID]",
"downloadPolicy": {
"essential": { // Possible keys: “essential”, “prefetch”, or “onDemand”
// Essential and prefetch download policies require a list of installation event types. For an on-demand download policy, the value for the “onDemand” key must be an empty object.
"installationEventTypes": [
// Remove undesired elements from this array.
"firstInstallation",
"subsequentUpdate"
]
}
},
"fileSelectors": [
// You can add as many file and/or directory selectors as you want.
{
"file": "[Path to File]"
},
{
"directory": "[Path to Directory]"
}
],
"platforms": [
// Remove undesired elements from this array.
"iOS",
"macOS",
"tvOS",
"visionOS"
]
} Add a downloader extension
import BackgroundAssets
import ExtensionFoundation
import StoreKit
@main
struct DownloaderExtension: StoreDownloaderExtension {
func shouldDownload(_ assetPack: AssetPack) -> Bool {
return true
}
} Download an asset pack
let assetPack = try await AssetPackManager.shared.assetPack(withID: "Tutorial")
// Await status updates for progress information
let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: "Tutorial")
Task {
for await statusUpdate in statusUpdates {
// …
}
}
// Download the asset pack
try await AssetPackManager.shared.ensureLocalAvailability(of: assetPack) Receive download status updates in Objective-C
@interface ManagedAssetPackDownloadDelegate : NSObject <BAManagedAssetPackDownloadDelegate>
@end
@implementation ManagedAssetPackDownloadDelegate
- (void)downloadOfAssetPackBegan:(BAAssetPack *)assetPack { /* … */ }
- (void)downloadOfAssetPackPaused:(BAAssetPack *)assetPack { /* … */ }
- (void)downloadOfAssetPackFinished:(BAAssetPack *)assetPack { /* … */ }
- (void)downloadOfAssetPack:(BAAssetPack *)assetPack hasProgress:(NSProgress *)progress { /* … */ }
- (void)downloadOfAssetPack:(BAAssetPack *)assetPack failedWithError:(NSError *)error { /* … */ }
@end Attach the delegate in Objective-C
static void attachDelegate(ManagedAssetPackDownloadDelegate *delegate) {
[[BAAssetPackManager sharedManager] setDelegate:delegate];
} Cancel an asset-pack download
let statusUpdates = AssetPackManager.shared.statusUpdates(forAssetPackWithID: "Tutorial")
for await statusUpdate in statusUpdates {
if case .downloading(_, let progress) = statusUpdate {
progress.cancel()
}
} Use an asset pack
// Read a file into memory
let videoData = try AssetPackManager.shared.contents(at: "Videos/Introduction.m4v")
// Open a file descriptor
let videoDescriptor = try AssetPackManager.shared.descriptor(for: "Videos/Introduction.m4v")
defer {
do {
try videoDescriptor.close()
} catch {
// …
}
} Remove an asset pack
// Remove the asset pack
try await AssetPackManager.shared.remove(assetPackWithID: "Tutorial")
// Redownload the asset pack
let assetPack = try await AssetPackManager.shared.assetPack(withID: "Tutorial")
try await AssetPackManager.shared.ensureLocalAvailability(of: assetPack) Info.plist
<key>BAAppGroupID</key>
<string>group.com.naturelab.thecoast</string>
<key>BAHasManagedAssetPacks</key>
<true/>
<key>BAUsesAppleHosting</key>
<true/> Resources
Related sessions
-
34 min -
26 min -
17 min