-
Unlock in-game content with StoreKit and Background Assets
Unlock native Apple In-App Purchases for your Unity game with the new StoreKit plug-in. Reduce download sizes with the new Background Assets plug-in, which delivers language-specific asset packs so each player gets just what they need. Plus, a new Steam Asset Converter helps you migrate existing builds.
Chapters
- 0:01 - Introduction
- 0:33 - Background Assets
- 1:35 - Localized asset packs
- 3:14 - Convert Steam depots to asset packs
- 4:15 - Unity plug-ins
- 5:52 - StoreKit and Background Assets sample code
- 8:25 - Game presence
- 9:10 - Next steps
Resources
Related Videos
WWDC26
Meet with Apple
WWDC25
WWDC22
-
Search this video…
Hello, I'm Sam, and I'm an engineer on the StoreKit team.
In this session, I'll dive into new tools to help you create the best games on Apple platforms. First, I'll cover updates to Background Assets. Then, I'll introduce new Unity plug-ins to help deliver a great In-App Purchase experience. Finally, I'll review how to enhance your presence on the App Store and Apple Games app. I'll start with updates to Background Assets.
Here's an app I've been working on called The Coast. It's a jam-packed game with many different levels to play. In addition to the game content, the app includes lots of audio, video, textures, and machine learning models, but these assets are only really needed at specific moments. Rather than downloading all of the assets upfront and taking up storage space, Managed Background Assets saves your players time and storage. The system automatically downloads your asset packs when they're needed to provide a great gaming experience for players. And for apps on the App Store, Apple can host up to 200 GB of assets per app, included in the Developer Program membership.
Apple-Hosted Background Assets is available starting with iOS, iPadOS, macOS, tvOS, and visionOS 26. For a deep dive on setup and API integration, check out the session "Discover Apple-Hosted Background Assets" from WWDC25.
In iOS 27, Managed Background Assets becomes even more powerful with localized asset packs. Localized asset packs greatly reduce the size of assets that players need to download by allowing the system to identify the player's preferred language selected in Settings, and only deliver assets for your game in that language. If asset packs for the user-selected language are not provided, the system automatically falls back to the closest language match.
In The Coast, I set English as the primary language, with French and German also available. Without localized asset packs, the system installs all of these assets to the player's device. After localizing my asset packs, if a player sets their system-wide language preference as German, the system only installs the German asset packs on their device. Localizing asset packs significantly decreases the storage that my game requires.
If I select English-UK as my system language preference, the system understands that an English-UK asset pack was not provided. As a fallback, the base language asset pack of the preferred user language is used, which in this case defaults to English-US. In another scenario, if I select Spanish as my system language preference, The Coast did not provide Spanish asset packs, and there is no similar regional variant available, so here the system falls back to the primary app language which is English.
To support localized asset packs in your game, update your asset pack manifest JSON files with a language tag.
If you're building a game on Steam, you may already manage your game's assets with depots. You can now more easily convert your Steam depots to asset packs to distribute with your game on Apple platforms.
To use the Steam asset converter on macOS, install Xcode 27, and run xcrun ba-package convert on the command line.
Three arguments are passed in: the ID of the asset pack, the language ID, if applicable, and the desired download policy.
Pass your Steam manifest build script as input, and an asset pack manifest with the specified name will be output. The same tool is coming soon to Linux and Windows.
Once the asset pack manifest is created, you can generate an asset pack archive by running ba-package again using the new manifest file as input, and an asset pack archive will be output.
The packaged asset pack archive is now ready to be used in your game! If you are developing with Unity, you can also utilize the updates to Background Assets. I'm excited to share two new plug-ins are joining the Apple Unity plug-in portfolio: Background Assets and StoreKit.
Apple Unity plug-ins enable your game to tap into the latest features and game services across Apple platforms.
The Background Assets and StoreKit plug-ins are available now for download, alongside Apple's existing plug-ins on GitHub.
The repository can be found in the resources of this session, and it provides instructions for building and installing the plug-ins.
Once you download the new Unity plug-ins, you can build them with the same Python script used to build the other Apple Unity plug-ins.
Both new plug-ins expose a C#-based Unity API which acts as a bridge to the underlying native framework.
To build, package, and test the plug-ins, use Xcode 27, Python 3, and Unity 2022 LTS or later. Check out the Meet with Apple session: "Chart your game's course to Apple platforms" to learn more about setting up and configuring your project with other Unity plug-ins from Apple. And for best practices when building your game, check out "Plug-in and play: Add Apple frameworks to your Unity game projects" from WWDC22.
Once the plug-ins are installed in your project, open your game in the Unity editor.
By adopting StoreKit in your project, you can reach players around the world, across all Apple platforms, and offer In-App Purchases through the App Store's safe and trusted commerce platform.
The C# version of the StoreKit APIs provides access to common flows like fetching and merchandising your In-App Purchase products with the Product API. And, you can initiate a purchase for products in your game using the Purchase API to display the system payment sheet.
After purchasing, use the PurchaseResult to check that the purchase was successful and the transaction IsVerified.
Then, deliver the purchased content to your players and call Finish() to complete the transaction.
Throughout your game's lifecycle, listen for new transactions with the Transaction.Updates sequence. A transaction is emitted through this sequence any time the system creates or updates transactions that occur outside your app or on other devices.
Here, I have an OnUpdate handler that is called at app startup inside a listener for transaction updates. For consumables, I first check that the transaction was not revoked and then grant access to the customer. For non-consumables and subscriptions, currentEntitlements is the source of truth for what a customer is entitled to. It already filters refunded, revoked, and expired states for nonconsumables and subscriptions, so we can grant access to customers once we know the transaction is verified. Finally, call Finish() on your verifiedTransaction.
When content is purchased by your players, you can use the Background Assets plug-in to ensure an asset pack is locally available and then start serving the content to players.
If a download is necessary, then you can monitor download progress, and update your game's UI by iterating over the status updates that the DownloadStatusUpdatesAsync method yields.
After configuring your game with the new plug-ins, export your project to Xcode, and leverage the powerful testing capabilities included with StoreKit Testing in Xcode and the Background Assets mock server. To set up StoreKit Testing in Xcode, create a StoreKit configuration file and add your test products.
Then, edit your target's scheme, select Run, and choose your StoreKit Configuration file in the drop-down.
Here is where you can also select the folder where your packaged asset packs are stored for the mock server to send to your game.
Now you're ready to build and run! When you run your project in Xcode 27, the Background Assets mock server automatically starts and attaches to your debug session to serve assets in your game. Sandbox testing is also available to help test the user experience with products you set up in App Store Connect.
When you're ready to submit your game to the App Store you can add new visuals to your product page header and search results to make your game stand out. The images and videos you add to your App Store search results will also appear in the Apple Games app, providing more ways to visually highlight your game.
Check out "Enhance your presence on the App Store" from WWDC26 to learn more about configuring these assets.
Finally, when your game is published and players purchase new content, they'll use the redesigned system payment sheet in iOS 27. It works great in landscape mode, so people can unlock content, and continue gaming. Before we conclude, let's review the next steps to improve your development workflow and create an even better gaming experience for players.
Further reduce your app size and efficiently deliver content to your players by uploading localized versions of your asset packs in App Store Connect.
Bring the power of the native Managed Background Assets and StoreKit APIs to your Unity game by installing new Apple Unity plug-ins.
When you finish updating your game, plan for how you can highlight your features using new image and video assets in the App Store and Apple Games app. Whether you're starting fresh or building on top of years of work, these new features will help you reach millions of players worldwide on Apple platforms. Thank you for joining me, and now, go take your game to the next level!
-
-
3:06 - Asset pack manifest for a localized asset pack
// Asset pack manifest { "assetPackID": "voice-english", "downloadPolicy": { /* … */ }, "language": "en-US", "sourceRoot": ".", "fileSelectors": [ /* … */ ], "platforms": [ /* … */ ] //… } -
3:27 - Convert a Steam depot to an asset pack manifest
# Convert a Steam depot to an asset pack manifest xcrun ba-package convert --asset-pack-id voice-english -l en-US --on-demand voice-english.vdf -o voice-english.json -
3:28 - Convert an asset pack manifest to an asset pack archive
# Convert an asset pack manifest to an asset pack archive xcrun ba-package voice-english.json -o voice-english.aar -
5:52 - Fetch and purchase products with the StoreKit plug-in
// Fetch and purchase products with the StoreKit plug-in using UnityEngine; using Apple.StoreKit; async void Start() { var products = await Product.FetchProducts(new[] { "com.thecoast.capecod" }); } -
6:01 - Fetch and purchase products with the StoreKit plug-in
// Fetch and purchase products with the StoreKit plug-in using UnityEngine; using Apple.StoreKit; async void Purchase(Product product) { var result = await product.Purchase(); if (result.Result == PurchaseResult.ResultEnum.Success && result.TransactionVerification.IsVerified) { // Unlock access to purchased content result.TransactionVerification.SafePayload.Finish(); } } -
6:23 - Listen for Transaction updates with the StoreKit plug-in
// Listen for Transaction updates with the StoreKit plug-in using UnityEngine; using Apple.StoreKit; public static class TransactionListener { public static void Initialize() => Transaction.Updates += OnUpdate; async void OnUpdate(VerificationResult<Transaction> result) { if (!result.IsVerified) return; var verifiedTransaction = result.SafePayload; // Consumables are not in CurrentEntitlements, so handle them inline if (verifiedTransaction.ProductType == ProductType.ProductTypeEnum.Consumable) { if (verifiedTransaction.RevocationDate != null) { // Revoke the consumable identified by verifiedTransaction.ProductId } else { // Grant access to the consumable } }else { // Non-consumables and subscriptions: re-read CurrentEntitlements as source of truth await foreach (var verificationResult in Transaction.GetCurrentEntitlements()) { if (!verificationResult.IsVerified) continue; // Grant access to the product } } verifiedTransaction.Finish(); } } -
7:13 - Download asset packs with the Background Assets plug-in
// Download asset packs with the Background Assets plug-in using Apple.BackgroundAssets; using UnityEngine; async void LoadTutorial(string language) { try { string assetPackId = $"tutorial-{language}"; AssetPackManifest manifest = await AssetPackManager.GetManifestAsync(); AssetPack assetPack = manifest.GetAssetPack(assetPackId); CancellationTokenSource tokenSource = new CancellationTokenSource(); _ = Task.Run(async () => { await foreach (AssetPackManager.DownloadStatusUpdate statusUpdate in AssetPackManager.DownloadStatusUpdatesAsync(assetPackId)) { // Update download progress in UI } }, tokenSource.Token); await AssetPackManager.EnsureLocalAvailabilityOfAssetPackAsync(assetPack); tokenSource.Cancel(); // Start tutorial with the locally available assets } catch (Exception exception) { // Handle the exception } }
-
-
- 0:01 - Introduction
New tools for building games on Apple platforms: updates to Background Assets, new Unity plug-ins for In-App Purchase, and ways to enhance your presence on the App Store and Apple Games app.
- 0:33 - Background Assets
Apple-Hosted Managed Background Assets save players time and storage by downloading asset packs only when needed. Now with Apple-hosting, up to 200 GB per app is included in the Developer Program.
- 1:35 - Localized asset packs
Localized asset packs greatly reduce the size of assets that players need to download by allowing the system to identify the player’s preferred language selected in Settings and only deliver assets for your game in that language.
- 3:14 - Convert Steam depots to asset packs
Learn how to bring your Steam depots into asset pack manifests and asset pack archives to ship along with your game on Apple platforms.
- 4:15 - Unity plug-ins
Two new Apple Unity plug-ins: Background Assets and StoreKit expose C# APIs that bridge to the native frameworks. Build and test with Xcode 27, Python 3, and Unity 2022 LTS or later.
- 5:52 - StoreKit and Background Assets sample code
Examples of how to use the C# version of the native StoreKit and Background Assets APIs in your game.
- 8:25 - Game presence
Make your game stand out with new visuals for your product page header and search results.
- 9:10 - Next steps
Ways to go further — upload localized asset packs in App Store Connect to reduce app size, adopt new Unity plug-ins, and highlight features with new image and video assets in the App Store and Apple Games app.