{"$schema": "https://raw.githubusercontent.com/guitaripod/wwdc-sessions/master/schema/transcript.schema.json", "id": "wwdc2026-213", "language": "eng", "source": "https://developer.apple.com/videos/play/wwdc2026/213", "wordCount": 2280, "segments": [{"start": 7.0, "text": "Hello!"}, {"start": 8.0, "text": "I'm Avery, an engineer on the Localization team."}, {"start": 11.0, "text": "Today I'd like to talk to you about translating your app"}, {"start": 14.0, "text": "using agents in Xcode."}, {"start": 17.0, "text": "When you localize your app into other languages,"}, {"start": 19.0, "text": "you expand your app's audience to millions more people around the world."}, {"start": 23.0, "text": "This is why at Apple,"}, {"start": 25.0, "text": "we're always striving to make it as easy as possible to localize your app."}, {"start": 30.0, "text": "In the past, traditional machine learning models have had a tough time with"}, {"start": 34.0, "text": "many aspects of software localization."}, {"start": 36.0, "text": "Modern LLMs have solved several of these problems"}, {"start": 39.0, "text": "and are great at general-purpose translation,"}, {"start": 42.0, "text": "but they can still struggle with software localization"}, {"start": 44.0, "text": "when they don't have the right context."}, {"start": 47.0, "text": "For example, consider the word 'book'."}, {"start": 50.0, "text": "Is this referring to something to read?"}, {"start": 52.0, "text": "Or perhaps an action I would take to reserve a room at a hotel."}, {"start": 57.0, "text": "These words look the same in English,"}, {"start": 59.0, "text": "but have completely separate translations in other languages!"}, {"start": 62.0, "text": "Without further context, the wrong translation could be chosen,"}, {"start": 66.0, "text": "which would be misleading."}, {"start": 68.0, "text": "The good news is, Xcode has been gaining context about your strings"}, {"start": 72.0, "text": "since the introduction of String Catalogs!"}, {"start": 75.0, "text": "Two years ago,"}, {"start": 76.0, "text": "String Catalogs started tracking where in code your strings are used."}, {"start": 80.0, "text": "Last year, they started tracking how your strings are used,"}, {"start": 83.0, "text": "so they could automatically generate descriptive comments."}, {"start": 87.0, "text": "And this year, we're excited to bring all of that context together!"}, {"start": 91.0, "text": "Beginning in Xcode 27,"}, {"start": 93.0, "text": "you can now translate your strings directly in Xcode using coding agents!"}, {"start": 98.0, "text": "I'll show you how you can add translations to your app,"}, {"start": 101.0, "text": "some techniques for reviewing and iterating on your translations,"}, {"start": 104.0, "text": "and finally, best practices you can follow to get the most out of these features."}, {"start": 109.0, "text": "Let's get started!"}, {"start": 111.0, "text": "I've been developing an app"}, {"start": 112.0, "text": "that helps me learn about different landmarks from around the world"}, {"start": 116.0, "text": "and I'd like to make my app available to people around the world too!"}, {"start": 119.0, "text": "Since I grew up in Canada, let's start with Canadian French."}, {"start": 124.0, "text": "I'm using SwiftUI, which means my app's UI is already localizable."}, {"start": 129.0, "text": "For example, I'm using APIs like Text and Button,"}, {"start": 133.0, "text": "which automatically expose their strings for localization."}, {"start": 137.0, "text": "I'm in a good place to start translation,"}, {"start": 139.0, "text": "so I'll ask an agent to translate my app into Canadian French,"}, {"start": 143.0, "text": "using the New Conversation button in Xcode's toolbar."}, {"start": 148.0, "text": "And with that,"}, {"start": 149.0, "text": "the agent and Xcode begin working together to translate my strings, step by step."}, {"start": 154.0, "text": "The agent starts by telling Xcode to prepare the project for localization."}, {"start": 160.0, "text": "Xcode begins by adding the language to the project settings"}, {"start": 163.0, "text": "in our case, Canadian French."}, {"start": 165.0, "text": "Then, Xcode builds all of your targets for your supported platforms."}, {"start": 170.0, "text": "This is important to ensure that"}, {"start": 171.0, "text": "all of the localizable strings in your project are properly discovered."}, {"start": 176.0, "text": "Finally, any newly discovered strings are added to String Catalogs."}, {"start": 180.0, "text": "If there aren't any String Catalogs in your project yet,"}, {"start": 183.0, "text": "Xcode creates them automatically."}, {"start": 186.0, "text": "By default, strings are added to a String Catalog called Localizable."}, {"start": 191.0, "text": "Of course, you can also use custom table names, to help you organize your strings."}, {"start": 195.0, "text": "For example, using the table name Greetings"}, {"start": 198.0, "text": "automatically puts your strings in a String Catalog called Greetings."}, {"start": 202.0, "text": "Looks like Xcode is done preparing the project."}, {"start": 204.0, "text": "Looking at the navigator on the left,"}, {"start": 207.0, "text": "I can see four brand new String Catalogs."}, {"start": 209.0, "text": "Great!"}, {"start": 211.0, "text": "Next, the agent selects the strings that need translating."}, {"start": 214.0, "text": "In my case, I've asked it to do the whole project,"}, {"start": 217.0, "text": "so it reads all four String Catalogs."}, {"start": 220.0, "text": "Finally, the real work can begin!"}, {"start": 223.0, "text": "The agent splits the strings into batches,"}, {"start": 226.0, "text": "delegating the translation work to individual subagents."}, {"start": 230.0, "text": "Xcode gives subagents context about each string being translated."}, {"start": 235.0, "text": "This can include information like where in code the string is used,"}, {"start": 238.0, "text": "or a list of strings that use similar terminology."}, {"start": 241.0, "text": "It can even reference how the string was translated in other languages!"}, {"start": 246.0, "text": "Let's take a look at the String Catalog on the right,"}, {"start": 248.0, "text": "to see what one subagent did when translating %lld items."}, {"start": 254.0, "text": "The placeholder %lld will be replaced with a number at runtime."}, {"start": 259.0, "text": "The string is varied by plural,"}, {"start": 261.0, "text": "which means in English, it says 'one item' or 'two items'."}, {"start": 266.0, "text": "The subagent has also varied this string in Canadian French,"}, {"start": 269.0, "text": "allowing it to say 'un élément' or 'deux éléments', with different spellings."}, {"start": 275.0, "text": "Other languages vary their plurals differently with more or fewer variations,"}, {"start": 279.0, "text": "Xcode makes sure subagents always know which variations are needed,"}, {"start": 283.0, "text": "no matter the language."}, {"start": 285.0, "text": "There are a lot of strings left for the subagents to translate,"}, {"start": 288.0, "text": "so I'll take a quick break and have a snack."}, {"start": 314.0, "text": "Ok!"}, {"start": 315.0, "text": "It looks like the subagents completed their stack before I could finish mine."}, {"start": 324.0, "text": "Let's see how it looks when I run the app in Canadian French."}, {"start": 328.0, "text": "I'll select my scheme in the toolbar,"}, {"start": 331.0, "text": "edit the scheme, select Run, and navigate to Options."}, {"start": 337.0, "text": "Here, I can change the app's language to Canadian French for the next debug run."}, {"start": 342.0, "text": "Now I'll build and run the app."}, {"start": 345.0, "text": "That looks great, très bien!"}, {"start": 347.0, "text": "I can see I'm on the right track to make my app available to more people"}, {"start": 351.0, "text": "all around the world."}, {"start": 353.0, "text": "Now, the app is currently using 'lieux d'intérêt'"}, {"start": 356.0, "text": "as the Canadian French translation for 'landmarks'."}, {"start": 359.0, "text": "This is a great, well-understood translation!"}, {"start": 363.0, "text": "However, since I grew up learning Canadian French, I have a couple of stylistic ideas"}, {"start": 367.0, "text": "that will help my app's translations really shine."}, {"start": 370.0, "text": "The term 'attraits', or 'attractions',"}, {"start": 373.0, "text": "is often used by the Canadian tourism industry"}, {"start": 375.0, "text": "in a similar way to how I'm using the word 'landmarks' in my app."}, {"start": 379.0, "text": "I like the idea of using this more laid-back term,"}, {"start": 382.0, "text": "especially since it's very familiar to French-speaking Canadians."}, {"start": 386.0, "text": "And for a little extra flair, I'll change the app name itself to"}, {"start": 390.0, "text": "'Attraits phares' or 'Flagship attractions'."}, {"start": 393.0, "text": "It's just as easy to make these changes"}, {"start": 395.0, "text": "as it was to add the original translations!"}, {"start": 398.0, "text": "I'll ask the agent to make the adjustments,"}, {"start": 400.0, "text": "and check back in, in a couple of minutes."}, {"start": 405.0, "text": "Great!"}, {"start": 406.0, "text": "Looking at some of the String Catalogs on the right,"}, {"start": 409.0, "text": "I can see the agent found all of the relevant strings"}, {"start": 411.0, "text": "and updated their translations, like the app name,"}, {"start": 414.0, "text": "and 'Draw a sketch of this landmark'."}, {"start": 417.0, "text": "So far, I've covered how easy it is to get started with your first translations."}, {"start": 423.0, "text": "However, it's just as easy to make translation a part of your workflow"}, {"start": 426.0, "text": "when adding new features to an app that's already localized."}, {"start": 430.0, "text": "In fact, I've just had a great idea for another feature I want to add to my app."}, {"start": 435.0, "text": "Let's build and localize it!"}, {"start": 437.0, "text": "Since this is a new feature, I'll start a new conversation."}, {"start": 444.0, "text": "I've asked the agent to add,"}, {"start": 446.0, "text": "and localize a fun label underneath the featured landmark,"}, {"start": 449.0, "text": "challenging people to discover all of the landmarks in the app."}, {"start": 453.0, "text": "Once the feature is built,"}, {"start": 454.0, "text": "the agent will translate it into Canadian French."}, {"start": 457.0, "text": "Looks like it's all done."}, {"start": 459.0, "text": "And check out the String Catalogs on the right,"}, {"start": 461.0, "text": "the agent added plural variations for the new string"}, {"start": 464.0, "text": "in both English and Canadian French,"}, {"start": 466.0, "text": "and the Canadian French string correctly uses 'attraits'"}, {"start": 470.0, "text": "as the translation for 'landmarks'."}, {"start": 472.0, "text": "This is really powerful!"}, {"start": 474.0, "text": "Without reading my previous conversation,"}, {"start": 476.0, "text": "while building a completely new feature,"}, {"start": 478.0, "text": "Xcode guided the agent to discover"}, {"start": 481.0, "text": "and reuse a translation for landmarks"}, {"start": 483.0, "text": "that it would not have chosen by default."}, {"start": 485.0, "text": "It's this kind of consistency"}, {"start": 487.0, "text": "that helps make the app that much more cohesive in Canadian French!"}, {"start": 491.0, "text": "Now that I've got some translations in place,"}, {"start": 493.0, "text": "I'd like to talk about some techniques for reviewing"}, {"start": 496.0, "text": "and iterating on localized strings."}, {"start": 498.0, "text": "Adding translations to your project is just one part of the story."}, {"start": 502.0, "text": "It's important to make sure"}, {"start": 504.0, "text": "that everything is working as you expect at runtime"}, {"start": 507.0, "text": "in other languages."}, {"start": 508.0, "text": "Different languages have different characteristics."}, {"start": 511.0, "text": "For example, sentences in Canadian French are longer on average"}, {"start": 515.0, "text": "than their English counterparts."}, {"start": 517.0, "text": "Since I just translated my new feature to Canadian French,"}, {"start": 520.0, "text": "I should make sure that all of the text still fits in my app's UI"}, {"start": 524.0, "text": "without truncating."}, {"start": 526.0, "text": "I'll ask the coding agent to render the UI for my new feature in Canadian French"}, {"start": 530.0, "text": "and look for truncations."}, {"start": 536.0, "text": "Check out the preview on the right, looks like it spotted a problem!"}, {"start": 540.0, "text": "The text for my new feature is truncating"}, {"start": 542.0, "text": "before the end of the sentence."}, {"start": 544.0, "text": "From here, I can investigate"}, {"start": 546.0, "text": "to see if this is simply a bug with my implementation,"}, {"start": 549.0, "text": "if this UI needs to be redesigned to accommodate the longer text,"}, {"start": 553.0, "text": "or if I should resort to asking the model for a shorter translation."}, {"start": 557.0, "text": "I'll add that to my to-do list for later."}, {"start": 560.0, "text": "You can use this technique to check for all kinds of issues that might crop up"}, {"start": 563.0, "text": "with different languages,"}, {"start": 565.0, "text": "including vertical clipping of text for tall languages like Thai,"}, {"start": 569.0, "text": "or incorrectly aligned views for right-to-left languages like Arabic."}, {"start": 574.0, "text": "This tight feedback loop is extremely helpful"}, {"start": 577.0, "text": "for catching and fixing issues as you develop your features."}, {"start": 581.0, "text": "To learn more about techniques and APIs for addressing issues around text layout,"}, {"start": 586.0, "text": "formatting, and more,"}, {"start": 587.0, "text": "watch \"Build multilingual-ready apps\""}, {"start": 590.0, "text": "and \"Get it right (to left)\"."}, {"start": 592.0, "text": "Besides getting feedback from a coding agent,"}, {"start": 595.0, "text": "it's also very important to get feedback from other sources."}, {"start": 598.0, "text": "As developers, one of our greatest strengths"}, {"start": 601.0, "text": "when using agents for programming is that we understand code."}, {"start": 605.0, "text": "This means that we can tell if an agent is producing code that fits our needs,"}, {"start": 610.0, "text": "is missing some nuances,"}, {"start": 611.0, "text": "or is heading down the wrong path."}, {"start": 614.0, "text": "That advantage disappears when using an agent"}, {"start": 616.0, "text": "to translate strings into languages we don't fluently speak."}, {"start": 620.0, "text": "This is where tools like TestFlight really shine."}, {"start": 623.0, "text": "Just as you'd ask people to test your exciting new features"}, {"start": 626.0, "text": "before you release them on the App Store,"}, {"start": 628.0, "text": "you should also ask native speakers to test your app"}, {"start": 631.0, "text": "in the languages you're adding."}, {"start": 633.0, "text": "With TestFlight, people can easily share feedback containing suggestions,"}, {"start": 637.0, "text": "or screenshots of localization issues,"}, {"start": 640.0, "text": "so you can address them before you release your localized experience to the public."}, {"start": 644.0, "text": "For example, I changed the translation for landmarks earlier"}, {"start": 648.0, "text": "because I speak Canadian French,"}, {"start": 649.0, "text": "but TestFlight would be a great place for me to receive similar suggestions"}, {"start": 653.0, "text": "for other languages!"}, {"start": 655.0, "text": "To learn more about collecting feedback for your app using TestFlight,"}, {"start": 658.0, "text": "check out the tech talk \"Get Started with TestFlight\"."}, {"start": 662.0, "text": "Before I wrap up,"}, {"start": 663.0, "text": "I'd like to mention a few tips and best practices"}, {"start": 666.0, "text": "that you can take advantage of"}, {"start": 667.0, "text": "to get the most out of the translation features in Xcode."}, {"start": 671.0, "text": "Having a well-localized app"}, {"start": 672.0, "text": "means that all user-facing strings should be translated."}, {"start": 676.0, "text": "Of course, this can only happen if your user-facing strings are localizable!"}, {"start": 681.0, "text": "As I mentioned near the beginning,"}, {"start": 682.0, "text": "SwiftUI code is localizable by default."}, {"start": 685.0, "text": "In the rest of your code,"}, {"start": 687.0, "text": "you will likely need to use String(localized:)"}, {"start": 690.0, "text": "or other APIs to ensure your strings are localizable."}, {"start": 693.0, "text": "For more details on the APIs you can use for localization,"}, {"start": 697.0, "text": "check out \"Code-along: Explore localization with Xcode\"."}, {"start": 701.0, "text": "Once you've made sure that all of your strings are localizable,"}, {"start": 704.0, "text": "consider the audience you're addressing with your app."}, {"start": 707.0, "text": "For example,"}, {"start": 708.0, "text": "a banking app would likely use very different style and terminology"}, {"start": 712.0, "text": "than an app for children."}, {"start": 714.0, "text": "By default, agents have access to Apple's translation expertise"}, {"start": 718.0, "text": "using language-specific style guides that ship in Xcode."}, {"start": 722.0, "text": "However, they'll also respect any translation guidance you provide."}, {"start": 726.0, "text": "For example, you can write a glossary"}, {"start": 728.0, "text": "containing specific translations you'd like to use for specific words,"}, {"start": 732.0, "text": "or a list of words that should always be left untranslated,"}, {"start": 735.0, "text": "like product names or trademarks,"}, {"start": 738.0, "text": "or even a plain-text description of the tone you wish your app to use."}, {"start": 742.0, "text": "To provide this guidance,"}, {"start": 744.0, "text": "you can add a section about translation to the AGENTS.md file,"}, {"start": 748.0, "text": "or any other similar file, you may already have in your project."}, {"start": 752.0, "text": "To avoid loading this additional context even when doing non-translation tasks,"}, {"start": 757.0, "text": "we recommend simply referring to a file called TRANSLATION.md,"}, {"start": 762.0, "text": "in which you write all of your translation guidance."}, {"start": 764.0, "text": "The agent should only choose to read the document"}, {"start": 766.0, "text": "when working on translation-related tasks."}, {"start": 769.0, "text": "Aside from translation guidance, there are a few other things to consider."}, {"start": 774.0, "text": "Translating an app is a complex and long-running task,"}, {"start": 777.0, "text": "especially when ensuring translations use consistent terminology"}, {"start": 781.0, "text": "across the project."}, {"start": 782.0, "text": "When thinking about which model to use,"}, {"start": 784.0, "text": "consider using one with a large context window"}, {"start": 787.0, "text": "that excels at completing extended requests,"}, {"start": 789.0, "text": "as these models are best suited for translation work."}, {"start": 793.0, "text": "It's also important to note"}, {"start": 794.0, "text": "that some languages appear less frequently than others in the training data"}, {"start": 798.0, "text": "that most models use,"}, {"start": 800.0, "text": "which could cause agents to produce"}, {"start": 802.0, "text": "lower-quality translations for those languages."}, {"start": 805.0, "text": "Some specific models"}, {"start": 806.0, "text": "may also perform better or worse at translating certain languages."}, {"start": 811.0, "text": "Consult documentation from model providers"}, {"start": 813.0, "text": "for more information on the distribution of languages in their training data."}, {"start": 818.0, "text": "And finally, if you're handling localizations exported from Xcode,"}, {"start": 822.0, "text": "you can check for the leveraged-mt state qualifier"}, {"start": 826.0, "text": "to understand which translations were provided by an agent."}, {"start": 830.0, "text": "I encourage you to explore translating your app"}, {"start": 832.0, "text": "using agents in Xcode on your own."}, {"start": 835.0, "text": "Try asking an agent to translate your app into a new language."}, {"start": 839.0, "text": "Or, add a new feature,"}, {"start": 841.0, "text": "and translate it, into the languages your app already supports."}, {"start": 845.0, "text": "Once you have translations,"}, {"start": 846.0, "text": "use the various agentic tools in Xcode"}, {"start": 849.0, "text": "to help you find and fix localization issues,"}, {"start": 852.0, "text": "and gather feedback from native speakers using tools such as TestFlight."}, {"start": 856.0, "text": "When you have an idea of where it's needed,"}, {"start": 858.0, "text": "consider providing extra translation guidance to agents"}, {"start": 862.0, "text": "to help make sure all of your translations are great going forward."}, {"start": 866.0, "text": "And finally, if you haven't already,"}, {"start": 868.0, "text": "check out \"Xcode, agents, and you\""}, {"start": 871.0, "text": "to learn about all of the other amazing things you can do with agents in Xcode."}, {"start": 876.0, "text": "Thank you for watching,"}, {"start": 877.0, "text": "and I hope these new translation features"}, {"start": 879.0, "text": "will help you reach new people all around the world with your apps."}, {"start": 882.0, "text": "À bientôt!"}]}