Streaming is available in most browsers,
and in the Developer app.
-
What's new in App Clips
Explore the latest updates to App Clips! Discover how we've made your App Clip even easier to build with improvements to the size limit as well as CloudKit and keychain usage. We'll also show you how to use our validation tool to verify your App Clip and automate workflows for your advanced App Clip experiences using App Store Connect.
Resources
Related Videos
WWDC21
WWDC20
-
Download
♪ ♪ Hi. I'm Charles Ying. Welcome to What's new in App Clips. An App Clip is a small part of an app. They're light and fast, and easy to discover, so you can quickly get what you need right when you need it. They can be found in Messages, Maps, Spotlight, and Safari, or out in the world with QR codes and App Clip Codes. One really cool example is Toast. Toast's app clip lets you scan a QR code to pay for your food right at your table! Toast configured their App Clip to open from an existing QR code printed on a receipt. The App Clip has resulted in users checking out faster, and more users choosing to install the full app. Building an App Clip into an existing flow is a great way to streamline your experience.
Today you'll learn about new features that let your users do more with your App Clip, and make developing App Clips even easier. Let's start with the App Clip size limit.
App Clips are light and fast, and designed for speed. To make App Clips feel instant, they need to be small. And since wireless networks are faster than they were two years ago, I'm happy to say that new in iOS 16, App Clips can now be up to 15 MB in size. This gives you more room to build your ideal experience. Set your App Clip's minimum version to iOS 16 for the new limit, or stay under 10 MB to be compatible with iOS 15 and earlier. Either way, you can always download additional resources after your App Clip launches. Speed is still key to a great experience. Your users won't always be in locations with a fast network, so optimizing your App Clip is still as critical as ever. To learn more about optimizing your App Clip, please watch, "Build light and fast App Clips”. Next, I'm really excited to show you a simple new tool that makes sure your App Clip experience or universal link is set up correctly. Here's how it works. On your iPhone or iPad, go to Developer Settings and under App Clips Testing, select Diagnostics. Now, enter your URL. You can turn on Developer Settings by connecting your device to Xcode. iOS will check your URL's configuration. If everything is set up right, you'll see these green checkboxes.
But, if there's something wrong, you'll see a screen like this one that tells you exactly what's happening. This will help you fix problems like Safari's banner not showing, or navigating to a web page instead of your App Clip. Each diagnostic has a link to documentation to explain the configuration step further. Now you'll be able to see exactly what's wrong.
App Clip diagnostics checks App Clip experiences that use physical codes, Safari and iMessage, and it will also check your universal link associated domains configuration. This simple new tool makes it so much easier to get your configuration right.
Next, CloudKit.
CloudKit is a framework that lets your app access data stored on iCloud. Up until now, CloudKit has not been available for App Clips. Your App Clip might be using a server to read data or resources.
New in iOS 16, App Clips can also read data and resources stored in a CloudKit public database. You can now share the same code, access the same data in both your app and App Clip with all the power and scale CloudKit provides. An important difference between apps and App Clips is that App Clips can read from a public database but can't write data to CloudKit. App Clips also can't use cloud documents and the key-value store. This keeps the promise to users that when an App Clip isn't used anymore, iOS will delete the App Clip and its data.
To enable CloudKit for your App Clip in Xcode, open your App Clip target's Signing and Capabilities tab, and select the CloudKit container you want your App Clip to use. This CloudKit container can be a new or existing container shared with your full app.
Here's an example of how to read CloudKit public data from your App Clip. Create a CKContainer with the container's identifier and access the publicCloudDatabase property. Then fetch the record you want from the public database.
Next, keychain migration.
Today, when you want to transfer sensitive information, like authentication tokens and payment information from your App Clip to your full app, your App Clip would store this data in a shared app group container. iOS saves this data when a user upgrades from your App Clip to your full app.
Your full app reads the app group container and stores that information in the keychain.
However, the keychain is the ideal place to securely store this type of information. New this year, when a user installs your app, items stored in your App Clip's keychain are transferred from your App Clip to your app. Now your App Clip can simply store secure items in the keychain and they will be moved to your app when it's installed.
Shared keychain groups and iCloud Keychain are not supported. This keeps the promise to users that keychain information won't stick around when an App Clip isn't used anymore.
Here's an example of how to store and read login information in the keychain. The code is the same for both app and App Clip. You can add new items to the keychain with SecItemAdd. And fetch these items from the keychain with SecItemCopyMatching. And add a label to your items to help your full app identify that the items were saved by your App Clip.
Finally, the App Clip experiences API. As your app clip grows, you'll have more and more advanced App Clip experiences, each with their own information or location. You need an easy way to add and update all of these experiences. App Store Connect has an App Clip experiences web API that's designed to automate this workflow. Let's look at an example that uses this API to add an advanced App Clip experience.
First, get the App Clip resource ID. Next, upload your header image. Last, create the advanced App Clip experience. First, let's find the resource ID for the app clip. Call the web API with your app's item ID and App Clip bundle ID. And from the response, save the App Clip resource ID for later. Next, upload a header image for the advanced App Clip experience. Save the header image's resource ID for the next step. Last, with your App Clip resource ID and your header image ID, we can now create your advanced App Clip experience.
There are three dictionaries to fill in: attributes, relationships, and included.
In the attributes dictionary, add information like the action name, which category and language, and the link for the advanced App Clip experience. If your advanced experience is tied to a Maps location, add a place dictionary. In the place dictionary, add the matching Maps business place name, a map action, and the map coordinates. In the relationships dictionary, add the App Clip resource ID and the header image ID. And in the included dictionary, add a localized title and subtitle for the advanced App Clip experience. And that's it! With this App Store Connect API, you can fully automate creating advanced App Clip experiences. To learn more about App Store Connect, check out “Automating App Store Connect” and “What's new in App Store Connect” from WWDC 2020.
To wrap up, the new App Clip size limit gives you more room to build your ideal experience. App Clip diagnostics tools are a great way to understand your App Clip and universal link configuration end to end. CloudKit and keychain can ease your development by sharing more code with your app. And the App Clip experiences API automates the workflow for managing your advanced App Clip experiences. To learn more about developing App Clips, please watch “What's new in App Clips” from WWDC 2021 and “Design great App Clips” from WWDC 2020.
You developers have made such great App Clips. They're so creative! We hope these new features help you build your next great App Clip. Thanks for watching! ♪ ♪
-
-
4:41 - Read your CloudKit public database from your App Clip
// Read your CloudKit public database from your App Clip let container = CKContainer.default() let publicDatabase = container.publicCloudDatabase let record = try await publicDatabase.record(for: CKRecord.ID(recordName: "A928D582-9BB6-E9C5-7881-E4EAF615E0CD")) if let title = record["Title"] as? String, let description = record["Description"] as? String { print(“Fetched a food item from CloudKit: \(title) \(description)") }
-
6:03 - Read and Write from your App Clip's keychain
// Write authentication token to App Clip keychain let addSecretsQuery: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecValueData as String: "smoothie-secret".data(using: .utf8), kSecAttrLabel as String: "foodsample-appclip" ] SecItemAdd(addSecretsQuery as CFDictionary, nil) // Read authentication token from app or App Clip var readSecretsQuery: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecReturnAttributes as String: true, kSecAttrLabel as String: "foodsample-appclip", kSecReturnData as String: true ] var secretsCopy: AnyObject? SecItemCopyMatching(readSecretsQuery as CFDictionary, &secretsCopy)
-
7:10 - Get your App Clip resource ID
# Get the App Clip resource ID GET /v1/apps/1234567890/appClips?filter[bundleId]=com.example.foodsample.Clip # Response { "data": { "attributes": { "bundleId": "com.example.foodsample.Clip" }, "id": "726ad1bb-3e1b-40eb-a986-d8a9897e4f1e" } }
-
7:25 - Upload a header image for the advanced App Clip experience
# Upload a header image for the advanced App Clip experience POST /v1/appClipAdvancedExperienceImages { "data": { "type": "appClipAdvancedExperienceImages", "attributes": { "fileName": "Hero_image_US.png", "fileSize": 43500 } } } # Response { "data": { "attributes": "..." "id": "91c52741-832b-48a2-8935-1797655edbe7" } }
-
7:34 - Create the advanced App Clip experience
# Create advanced App Clip experience POST /v1/appClipAdvancedExperiences { "data": { "type": "appClipAdvancedExperiences", "attributes": { "action": “OPEN", "businessCategory": "FOOD_AND_DRINK", "defaultLanguage": "EN", "isPoweredBy": true, "link": "https://fruta.example.com/restauraunt/simply_salad", "place": { "names": [ "Caffe Macs" ], "mapAction": "RESTAURANT_ORDER_FOOD", "displayPoint": { "coordinates": { "latitude": 37.33611, "longitude": -122.00731 }, "source": "CALCULATED" } } }, "relationships": { "appClip": { "data": { "type": "appClip", "id": "726ad1bb-3e1b-40eb-a986-d8a9897e4f1e" } }, "headerImage": { "data": { "type": "appClipAdvancedExperienceImages", "id": "91c52741-832b-48a2-8935-1797655edbe7" } } }, "included": { "type": "appClipAdvancedExperienceLocalizations", "attributes": { "language": "EN", "subtitle": "Fresh salad every day", "title": "Simply Salad" } } } }
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.