{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-209", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/209", "wordCount": 2161, "segments": [{"start": 8.0, "text": "Hi, I'm Shaun."}, {"start": 9.0, "text": "And welcome to \"What's New in Wallet\"."}, {"start": 11.0, "text": "Since their introduction,"}, {"start": 13.0, "text": "passes have become an essential part of how people move through their day."}, {"start": 16.0, "text": "From picking up a morning coffee, to tapping through transit gates,"}, {"start": 20.0, "text": "to checking in and boarding a flight,"}, {"start": 22.0, "text": "all without ever handing over a physical card."}, {"start": 26.0, "text": "Passes help people move through the world faster, more privately, and more securely."}, {"start": 32.0, "text": "In iOS 27, we're taking passes further than ever."}, {"start": 36.0, "text": "iOS 27 introduces a stunning new pass style called Poster Generic."}, {"start": 41.0, "text": "Four new barcode types, giving you more flexibility at the point of presentation."}, {"start": 46.0, "text": "And a powerful new way for passes to surface relevant actions,"}, {"start": 50.0, "text": "right below the pass face."}, {"start": 53.0, "text": "And we're also introducing a brand new suite of developer tools for Mac"}, {"start": 58.0, "text": "and server platforms, making it easier than ever to design,"}, {"start": 62.0, "text": "personalize, and build great passes."}, {"start": 66.0, "text": "We have a lot to cover,"}, {"start": 67.0, "text": "so let's dive straight in with the brand new pass style, Poster Generic."}, {"start": 72.0, "text": "Poster Generic is a great fit for membership cards, loyalty programs,"}, {"start": 78.0, "text": "store cards, and anywhere you want bold, colorful artwork to take center stage."}, {"start": 86.0, "text": "The pass face consists of a background image,"}, {"start": 89.0, "text": "a primary logo,"}, {"start": 91.0, "text": "header fields,"}, {"start": 94.0, "text": "primary fields,"}, {"start": 96.0, "text": "a footer field,"}, {"start": 98.0, "text": "and lastly, a barcode if supplied."}, {"start": 101.0, "text": "To adopt this pass style, in the pass.json of your pass bundle,"}, {"start": 105.0, "text": "specify the posterGeneric top-level style key."}, {"start": 109.0, "text": "Then add your content with the usual pass fields structure,"}, {"start": 113.0, "text": "and the pass will take care of laying everything out across the pass face."}, {"start": 118.0, "text": "One thing to keep in mind,"}, {"start": 119.0, "text": "is that the pass face supports a single footer field,"}, {"start": 123.0, "text": "so if you include more than one, only the first will be displayed."}, {"start": 128.0, "text": "Poster Generic requires iOS 27 or later."}, {"start": 132.0, "text": "To support customers on iOS 26 and earlier,"}, {"start": 135.0, "text": "we recommend including the existing generic top-level style key,"}, {"start": 139.0, "text": "alongside the posterGeneric style key in your pass.json,"}, {"start": 143.0, "text": "with relevant fields under each."}, {"start": 146.0, "text": "That way, customers who have not yet made the update to iOS 27,"}, {"start": 150.0, "text": "will still be able to add your pass to Wallet."}, {"start": 153.0, "text": "Next, in iOS 27, passes support four new barcode types."}, {"start": 159.0, "text": "EAN-13, Code 39, Codabar, and ITF."}, {"start": 165.0, "text": "These are specified using the existing barcode object"}, {"start": 168.0, "text": "and barcodes array in your pass.json."}, {"start": 173.0, "text": "For example, to present your barcode in Codabar format,"}, {"start": 177.0, "text": "set the format of your barcode to PKBarcodeFormatCodabar."}, {"start": 183.0, "text": "You can find the full list of format definitions"}, {"start": 186.0, "text": "in the Wallet Passes documentation."}, {"start": 188.0, "text": "Because previous versions of iOS do not support these new formats,"}, {"start": 192.0, "text": "we strongly recommend providing an array of barcodes in priority order."}, {"start": 196.0, "text": "By providing multiple barcodes,"}, {"start": 198.0, "text": "you give the system the best chance of rendering a barcode your hardware can scan,"}, {"start": 203.0, "text": "regardless of which operating system version your customer is on."}, {"start": 208.0, "text": "If you only provide one of the new barcode types and nothing else,"}, {"start": 212.0, "text": "the pass will not render a barcode on iOS 26 and earlier."}, {"start": 217.0, "text": "So we recommend leading with your preferred format,"}, {"start": 220.0, "text": "and falling back gracefully."}, {"start": 226.0, "text": "Now we do recognize that there are some circumstances,"}, {"start": 230.0, "text": "where supporting multiple barcode types simply isn't an option."}, {"start": 234.0, "text": "If that's your situation, there are two things you should do."}, {"start": 238.0, "text": "First, surface the credential ID in a pass field"}, {"start": 241.0, "text": "so it can be entered manually, and make it easy to find."}, {"start": 246.0, "text": "Consider using a primaryField,"}, {"start": 248.0, "text": "or headerField, so it's prominent on the pass face."}, {"start": 252.0, "text": "Second, make sure your front-line staff are trained for manual entry workflows."}, {"start": 257.0, "text": "A pass that can't be scanned, shouldn't result in a blocked customer."}, {"start": 262.0, "text": "Getting this right,"}, {"start": 263.0, "text": "can mean the difference between a seamless experience and a frustrating one."}, {"start": 268.0, "text": "Next, lets talk about featured actions."}, {"start": 272.0, "text": "With the second generation event ticket introduced in iOS 18"}, {"start": 275.0, "text": "you can provide semantic URLs to expose additional user actions"}, {"start": 279.0, "text": "drawn below the pass, such as viewing the event schedule."}, {"start": 282.0, "text": "In iOS 27, there's a new flexible API,"}, {"start": 285.0, "text": "that allows you to provide actions for all pass styles."}, {"start": 289.0, "text": "In the top level of your pass.json, define the featuredActions key,"}, {"start": 293.0, "text": "which takes an array of action objects."}, {"start": 296.0, "text": "Each action is defined as a unique ID, the action type,"}, {"start": 299.0, "text": "and a value, such as a URL."}, {"start": 302.0, "text": "For example, to provide an action to view offers,"}, {"start": 306.0, "text": "I'd set the identifier to a unique ID,"}, {"start": 309.0, "text": "the action type to membershipBenefits, and a URL to navigate the user."}, {"start": 315.0, "text": "Wallet draws this below the pass, with an appropriate colorful icon"}, {"start": 320.0, "text": "and a localized call-to-action."}, {"start": 324.0, "text": "Each pass can contain up to two featured actions."}, {"start": 328.0, "text": "We recommend providing only the most meaningful"}, {"start": 331.0, "text": "and relevant actions to your customers,"}, {"start": 334.0, "text": "and provide your actions in priority order."}, {"start": 337.0, "text": "You can find the full list of supported actions types"}, {"start": 340.0, "text": "and their expected values in the Wallet Passes documentation."}, {"start": 344.0, "text": "Now, passes have gained a lot of features and functionality over the last decade."}, {"start": 349.0, "text": "And it can be hard to connect what is described in the pass bundle,"}, {"start": 352.0, "text": "to the visual representation presented on device."}, {"start": 356.0, "text": "So we're excited to announce a brand new app, for Mac,"}, {"start": 360.0, "text": "that makes designing passes easier than ever."}, {"start": 363.0, "text": "And it's called Pass Designer."}, {"start": 367.0, "text": "Pass Designer is a what-you-see-is-what-you-get editor,"}, {"start": 370.0, "text": "giving you a true-to-iOS rendering of your pass as you build it."}, {"start": 376.0, "text": "Pass Designer creates template files."}, {"start": 379.0, "text": "To convert a template into a personalized, signed pass ready for distribution,"}, {"start": 384.0, "text": "alongside Pass Designer"}, {"start": 386.0, "text": "we're also announcing a new Swift on Server package"}, {"start": 389.0, "text": "called Pass Builder."}, {"start": 391.0, "text": "Pass Builder runs on Mac and Linux."}, {"start": 395.0, "text": "It provides a Swift API,"}, {"start": 397.0, "text": "and a command-line executable, called buildpass."}, {"start": 401.0, "text": "My friend Stacey runs a doggy day care,"}, {"start": 403.0, "text": "and I want to help her create membership cards for each of her fluffy clients."}, {"start": 408.0, "text": "I'm going to use Pass Designer to design a template,"}, {"start": 411.0, "text": "and then use Pass Builder on Server to personalize the template,"}, {"start": 415.0, "text": "and distribute passes at scale."}, {"start": 418.0, "text": "Let's jump into Pass Designer."}, {"start": 421.0, "text": "And here we go."}, {"start": 422.0, "text": "A live preview of the pass on the right,"}, {"start": 425.0, "text": "and a sidebar to edit the pass on the left."}, {"start": 428.0, "text": "The sidebar allows you to configure the pass Identity & Signing configuration,"}, {"start": 433.0, "text": "the pass style, images, barcodes, fields,"}, {"start": 438.0, "text": "and semantics, if the pass style supports it."}, {"start": 441.0, "text": "So this is a bit of a blank canvas."}, {"start": 443.0, "text": "But I know Stacey takes some gorgeous portrait photos of each dog,"}, {"start": 447.0, "text": "so lets experiment with the new Poster Generic style"}, {"start": 450.0, "text": "and see how those photos look."}, {"start": 452.0, "text": "So I'll go into Style, and change the pass style to Poster Generic."}, {"start": 459.0, "text": "And then, I'm gonna navigate to Images in the sidebar"}, {"start": 463.0, "text": "and drag in a sample photo, Stacey has given me from my Desktop."}, {"start": 469.0, "text": "That looks like it fits quite nicely."}, {"start": 471.0, "text": "Now lets add some fields."}, {"start": 474.0, "text": "I'll navigate to Header Fields in the sidebar, and add a new header field."}, {"start": 480.0, "text": "I'm going to set the key to DOG_ID, the label to Member ID,"}, {"start": 484.0, "text": "and add a placeholder ID to see how it looks."}, {"start": 488.0, "text": "Great."}, {"start": 489.0, "text": "Now lets add some primary fields for dog name, and their favorite toy."}, {"start": 494.0, "text": "In the sidebar, I'm going to navigate to Primary Fields,"}, {"start": 499.0, "text": "and add a primary field for name."}, {"start": 503.0, "text": "I'll set the key to DOG_NAME."}, {"start": 506.0, "text": "Now here's a neat trick with the Poster Generic pass face,"}, {"start": 510.0, "text": "if I omit the label on the first primary field,"}, {"start": 514.0, "text": "we'll get the cool bold title for the field value."}, {"start": 519.0, "text": "So I'm going to type in a placeholder name of Finley."}, {"start": 522.0, "text": "And add a primary field for favorite toy."}, {"start": 525.0, "text": "So again, I'll navigate to Primary Fields,"}, {"start": 529.0, "text": "and add a new field."}, {"start": 533.0, "text": "I'll set the key to LOVES, the label to Loves,"}, {"start": 538.0, "text": "and add a placeholder value of Flying Disc."}, {"start": 541.0, "text": "And now lets make it super easy for Stacey to check each dog in and out of daycare,"}, {"start": 547.0, "text": "by encoding their member ID, as a barcode."}, {"start": 551.0, "text": "I'm going to head over to Barcode & NFC."}, {"start": 555.0, "text": "And write in a placeholder barcode message."}, {"start": 559.0, "text": "This works, but I don't think I need to use that much space for a QR code."}, {"start": 564.0, "text": "Lets try a narrow barcode type instead,"}, {"start": 567.0, "text": "such as PDF417."}, {"start": 570.0, "text": "I'm going to click on the Format picker,"}, {"start": 573.0, "text": "and select PDF417."}, {"start": 576.0, "text": "That looks much better."}, {"start": 578.0, "text": "Now lets add some finishing touches, by adding a Primary Logo."}, {"start": 583.0, "text": "I'll navigate to Images,"}, {"start": 585.0, "text": "and drag in the Primary Logo from my Desktop."}, {"start": 591.0, "text": "And adjusting the colors by navigating to Style,"}, {"start": 595.0, "text": "and setting the Label Color."}, {"start": 597.0, "text": "And the final finishing touch,"}, {"start": 599.0, "text": "adding \"Stacey's Doggy Day Care\" to the footer."}, {"start": 603.0, "text": "I'll navigate to Footer Fields, and add a new field."}, {"start": 609.0, "text": "And set the text value to Stacey's Doggy Day Care."}, {"start": 614.0, "text": "Now that's a cute pass, for a very cute dog."}, {"start": 619.0, "text": "The very last thing to do, is to save our template."}, {"start": 623.0, "text": "Pass Designer saves templates as pkpasstemplate files."}, {"start": 629.0, "text": "I'm going to go to File, then Save, and then save the template."}, {"start": 639.0, "text": "Now, I don't want to create an individual pass"}, {"start": 640.0, "text": "for every member of Stacey's Doggy Day Care in Pass Designer."}, {"start": 644.0, "text": "Instead, I want to personalize this template at scale,"}, {"start": 648.0, "text": "on a server, using Pass Builder."}, {"start": 651.0, "text": "I'm going to switch over to the Swift server,"}, {"start": 654.0, "text": "for Stacey's Doggy Day Care."}, {"start": 655.0, "text": "First, I'm going to add PassBuilder,"}, {"start": 658.0, "text": "as a dependency, to the Swift package manifest,"}, {"start": 661.0, "text": "and to the server target."}, {"start": 665.0, "text": "Now I'm going to implement this function createPass in the server source,"}, {"start": 669.0, "text": "to generate a personalized pass."}, {"start": 671.0, "text": "The function createPass receives a model already loaded from the database,"}, {"start": 675.0, "text": "with the dog's name, membership ID, their favorite toy,"}, {"start": 679.0, "text": "and a URL to a gorgeous photo of each dog."}, {"start": 683.0, "text": "Let's get started by first loading the template I made earlier,"}, {"start": 686.0, "text": "using the PassPackage type."}, {"start": 688.0, "text": "PassPackage provides a type-safe way to access and configure the pass bundle,"}, {"start": 694.0, "text": "including a pass property to interact with the contents of the pass.json."}, {"start": 699.0, "text": "Let's personalize the fields."}, {"start": 702.0, "text": "I'll call setValue on the pass fields property to set the dog's name,"}, {"start": 707.0, "text": "their membership ID and their favorite toy."}, {"start": 711.0, "text": "Now let's set the background image to the photo of the dog."}, {"start": 715.0, "text": "I'm going create an instance of PassImage, passing in a URL to the photo of the dog,"}, {"start": 721.0, "text": "and assigning it to the background image property on the pass package type."}, {"start": 725.0, "text": "And lets configure the barcode,"}, {"start": 727.0, "text": "so dogs can be quickly checked in and out of day care."}, {"start": 731.0, "text": "I'll create a Pass.Barcode,"}, {"start": 733.0, "text": "with the encoded message being the dog's membership ID,"}, {"start": 736.0, "text": "and using the PDF417 format."}, {"start": 741.0, "text": "And lastly, I think it'd be great to have a featured action"}, {"start": 745.0, "text": "for clients to view their membership,"}, {"start": 747.0, "text": "so lets add that by setting a Pass.Action on featuredActions."}, {"start": 752.0, "text": "And just like that the server is generating a personalized pass."}, {"start": 757.0, "text": "Now, we need to build our pass and sign it for distribution."}, {"start": 762.0, "text": "As a reminder, to build and sign a pass for Wallet,"}, {"start": 765.0, "text": "you need to generate and write a manifest of the contents of your pass,"}, {"start": 769.0, "text": "into your pass bundle."}, {"start": 771.0, "text": "Then create a detached signature of the manifest,"}, {"start": 774.0, "text": "and write the signature into your pass bundle."}, {"start": 778.0, "text": "Then compress the resulting directory and add the .pkpass file extension."}, {"start": 784.0, "text": "Pass Builder takes care of all of that for you."}, {"start": 787.0, "text": "You just need to provide the certificates."}, {"start": 790.0, "text": "Going back to the server source."}, {"start": 792.0, "text": "Using the PassCertificate type,"}, {"start": 794.0, "text": "I'm going to load the pass signing certificate,"}, {"start": 797.0, "text": "and the WWDR intermediate certificate."}, {"start": 801.0, "text": "Next, I'm going to create an instance of PassSigner,"}, {"start": 805.0, "text": "passing in the certificates."}, {"start": 806.0, "text": "And finally, I'm going to call the signPass function on PassSigner,"}, {"start": 811.0, "text": "passing in the personalized package I made earlier,"}, {"start": 815.0, "text": "and the URL on disk, to write the signed pass for distribution."}, {"start": 820.0, "text": "And then return the URL."}, {"start": 823.0, "text": "And now Stacey's doggy day care has gorgeous Wallet Passes for every client."}, {"start": 830.0, "text": "Pass Builder can also be used from other programming languages."}, {"start": 834.0, "text": "The swift-java project can generate native Java bindings for the Swift API,"}, {"start": 839.0, "text": "allowing you to invoke Pass Builder from the Java runtime."}, {"start": 843.0, "text": "We're also making protobuf definitions of the pass package format available,"}, {"start": 847.0, "text": "allowing you to generate type-safe models in your preferred programming language."}, {"start": 852.0, "text": "You can then generate a customization message,"}, {"start": 855.0, "text": "and invoke the buildpass command line executable,"}, {"start": 858.0, "text": "to personalize and sign your pass."}, {"start": 861.0, "text": "For more information on using swift-java,"}, {"start": 863.0, "text": "check out the \"Explore Swift and Java interoperability\" developer session."}, {"start": 868.0, "text": "And for documentation on the buildpass command line,"}, {"start": 871.0, "text": "see the Pass Builder developer documentation."}, {"start": 874.0, "text": "Both of which are linked in the session description."}, {"start": 878.0, "text": "And that's a brief end-to-end demo of Pass Designer and Pass Builder."}, {"start": 883.0, "text": "From designing a template,"}, {"start": 884.0, "text": "to personalizing it, to signing it for distribution."}, {"start": 889.0, "text": "You can find links to download Pass Designer, the Pass Builder source,"}, {"start": 893.0, "text": "and comprehensive documentation in the session description."}, {"start": 898.0, "text": "I've covered a lot today, so for next steps."}, {"start": 901.0, "text": "Check out Pass Designer."}, {"start": 903.0, "text": "Use Pass Designer to experiment with the new Poster Generic style,"}, {"start": 907.0, "text": "and check if it's the right fit for your pass."}, {"start": 911.0, "text": "If you plan on adopting any of the new barcode types,"}, {"start": 914.0, "text": "make a plan for providing graceful fallbacks."}, {"start": 918.0, "text": "And take a moment"}, {"start": 919.0, "text": "to identify the most meaningful and relevant actions for your customers,"}, {"start": 923.0, "text": "then bring them to life, with featured actions."}, {"start": 927.0, "text": "This is a new chapter for building Wallet Passes,"}, {"start": 930.0, "text": "and we're so excited to see all the amazing passes you're going to create."}, {"start": 935.0, "text": "Thanks for watching, and have a wonderful WWDC."}]}