View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Videos

Abrir menú Cerrar menú
  • Colecciones
  • Todos los videos
  • Información

Más videos

  • Información
  • Código
  • What's new in Foundation

    Discover how the latest updates to Foundation can help you improve your app's localization and internationalization support. Find out about the new AttributedString, designed specifically for Swift, and learn how you can use Markdown to apply style to your localized strings. Explore the grammar agreement engine, which automatically fixes up localized strings so they match grammatical gender and pluralization. And we'll take you through improvements to date and number formatting that simplify complex requirements while also improving performance.

    Recursos

    • Foundation
      • Video HD
      • Video SD

    Videos relacionados

    WWDC23

    • Unlock the power of grammatical agreement

    WWDC22

    • Swift Regex: Beyond the basics

    WWDC21

    • Localize your SwiftUI app
    • Meet AsyncSequence
    • Streamline your localized strings
    • What's new in SwiftUI
  • Buscar este video…
    • 2:50 - Attributed String Basics

      func attributedStringBasics(important: Bool) {
          var thanks = AttributedString("Thank you!")
          thanks.font = .body.bold()
      
          var website = AttributedString("Please visit our website.")
          website.font = .body.italic()
          website.link = URL(string: "http://www.example.com")
      
          var container = AttributeContainer()
          if important {
              container.foregroundColor = .red
              container.underlineColor = .primary
          } else {
              container.foregroundColor = .primary
          }
      
          thanks.mergeAttributes(container)
          website.mergeAttributes(container)
      
          print(thanks)
          print(website)
      }
    • 4:24 - Attributed String Characters

      func attributedStringCharacters() {
          var message = AttributedString(localized: "Thank you! _Please visit our [website](http://www.example.com)._")
          let characterView = message.characters
          for i in characterView.indices where characterView[i].isPunctuation {
              message[i..<characterView.index(after: i)].foregroundColor = .orange
          }
      
          print(message)
      }
    • 5:12 - Attributed String Runs (Part 1)

      func attributedStringRuns() {
          let message = AttributedString(localized: "Thank you! _Please visit our [website](http://www.example.com)._")
          let runCount = message.runs.count
          // runCount is 4
          print(runCount)
      
          let firstRun = message.runs.first!
          let firstString = String(message.characters[firstRun.range])
          // firstString is "Thank you!"
          print(firstString)
      }
    • 5:49 - Attributed String Runs (Part 2)

      func attributedStringRuns2() {
          let message = AttributedString(localized: "Thank you! _Please visit our [website](http://www.example.com)._")
      
          let linkRunCount = message.runs[\.link].count
          // linkRunCount is 3
          print(linkRunCount)
      
          var insecureLinks: [URL] = []
          for (value, range) in message.runs[\.link] {
              if let v = value, v.scheme != "https" {
                  insecureLinks.append(v)
              }
          }
          // insecureLinks is [http://www.example.com]
          print(insecureLinks)
      }
    • 6:36 - Attributed String Mutation

      func attributedStringMutation() {
          var message = AttributedString(localized: "Thank you! _Please visit our [website](http://www.example.com)._")
      
          if let range = message.range(of: "visit") {
              message[range].font = .body.italic().bold()
              message.characters.replaceSubrange(range, with: "surf")
          }
      
          print(message)
      }
    • 7:29 - Localized Strings

      func prompt(for document: String) -> String {
          String(localized: "Would you like to save the document “\(document)”?")
      }
      
      func attributedPrompt(for document: String) -> AttributedString {
          AttributedString(localized: "Would you like to save the document “\(document)”?")
      }
    • 9:34 - Codable Attributed Strings

      struct FoodItem: Codable {
          // Placeholder type to demonstrate concept
          var name: String
      }
      
      struct Receipt: Codable {
          var items: [FoodItem]
          var thankYouMessage: AttributedString
      }
      
      func codableBasics() {
          let message = AttributedString(localized: "Thank you! _Please visit our [website](http://www.example.com)._")
          let receipt = Receipt(items: [FoodItem(name: "Juice")], thankYouMessage: message)
      
          let encoded = try! JSONEncoder().encode(receipt)
          let decodedReceipt = try! JSONDecoder().decode(Receipt.self, from: encoded)
      
          print("\(decodedReceipt.thankYouMessage)")
      }
    • 10:42 - Markdown Decodable Attribute

      enum RainbowAttribute : CodableAttributedStringKey, MarkdownDecodableAttributedStringKey {
          enum Value : String, Codable {
              case plain
              case fun
              case extreme
          }
      
          public static var name = "rainbow"
      }
    • 11:30 - Custom Markdown Syntax

      This text contains [a link](http://www.example.com).
      
      This text contains ![an image](http://www.example.com/my_image.gif).
      
      This text contains ^[an attribute](rainbow: 'extreme').
    • 12:27 - Custom Markdown Attributes

      This text contains ^[an attribute](rainbow: 'extreme').
      
      This text contains ^[two attributes](rainbow: 'extreme', otherValue: 42).
      
      This text contains ^[an attribute with 2 properties](someStuff: {key: true, key2: false}).
    • 13:15 - Attribute Scopes

      extension AttributeScopes {
          struct CaffeAppAttributes : AttributeScope {
              let rainbow: RainbowAttribute
      
              let swiftUI: SwiftUIAttributes
          }
      
          var caffeApp: CaffeAppAttributes.Type { CaffeAppAttributes.self }
      }
      
      func customAttributesFromMarkdown() {
          let header = AttributedString(localized: "^[Fast & Delicious](rainbow: 'extreme') Food", including: \.caffeApp)
      
          print(header)
      }
    • 17:28 - Formatting Dates

      func formattingDates() {
          // Note: This will use your current date & time plus current locale. Example output is for en_US locale.
          let date = Date.now
      
          let formatted = date.formatted()
          // example: "6/7/2021, 9:42 AM"
          print(formatted)
      
          let onlyDate = date.formatted(date: .numeric, time: .omitted)
          // example: "6/7/2021"
          print(onlyDate)
      
          let onlyTime = date.formatted(date: .omitted, time: .shortened)
          // example: "9:42 AM"
          print(onlyTime)
      }
    • 18:16 - Formatting Dates With Styles

      func formattingDatesWithStyles() {
          // Note: This will use your current date & time plus current locale. Example output is for en_US locale.
          let date = Date.now
      
          let formatted = date.formatted(.dateTime)
          // example: "6/7/2021, 9:42 AM"
          print(formatted)
      }
    • 18:36 - Formatting Dates - More Examples

      func formattingDatesMoreExamples() {
          // Note: This will use your current date & time plus current locale. Example output is for en_US locale.
          let date = Date.now
      
          let formatted = date.formatted(.dateTime.year().day().month())
          // example: "Jun 7, 2021"
          print(formatted)
      
          let formattedWide = date.formatted(.dateTime.year().day().month(.wide))
          // example: "June 7, 2021"
          print(formattedWide)
      
          let formattedWeekday = date.formatted(.dateTime.weekday(.wide))
          // example: "Monday"
          print(formattedWeekday)
      
          let logFormat = date.formatted(.iso8601)
          // example: "20210607T164200Z"
          print(logFormat)
      
          let fileNameFormat = date.formatted(.iso8601.year().month().day().dateSeparator(.dash))
          // example: "2021-06-07"
          print(fileNameFormat)
      }
    • 20:30 - Formatting Intervals

      func formattingIntervals() {
          // Note: This will use your current date & time plus current locale. Example output is for en_US locale.
          let now = Date.now
          // Note on time calculations: This represents the absolute point in time 5000 seconds from now. For calculations that are in terms of hours, days, etc., please use Calendar API.
          let later = now + TimeInterval(5000)
      
          let range = (now..<later).formatted()
          // example: "6/7/21, 9:42 – 11:05 AM"
          print(range)
      
          let noDate = (now..<later).formatted(date: .omitted, time: .complete)
          // example: "9:42:00 AM PDT – 11:05:20 AM PDT"
          print(noDate)
      
          let timeDuration = (now..<later).formatted(.timeDuration)
          // example: "1:23:20"
          print(timeDuration)
      
          let components = (now..<later).formatted(.components(style: .wide))
          // example: "1 hour, 23 minutes, 20 seconds"
          print(components)
      
          let relative = later.formatted(.relative(presentation: .named, unitsStyle: .wide))
          // example: "in 1 hour"
          print(relative)
      }
    • 21:39 - Demo - SwiftUI and AttributedString

      import SwiftUI
      
      struct ContentView: View {
          @State var date = Date.now
          @Environment(\.locale) var locale
      
          var dateString : AttributedString {
              var str = date.formatted(.dateTime
                                          .minute()
                                          .hour()
                                          .weekday()
                                          .locale(locale)
                                          .attributed)
      
              let weekday = AttributeContainer
                  .dateField(.weekday)
      
              let color = AttributeContainer
                  .foregroundColor(.orange)
      
              str.replaceAttributes(weekday, with: color)
      
              return str
          }
      
      
          var body: some View {
              VStack {
                  Text("Next free coffee")
                  Text(dateString).font(.title2)
              }
              .multilineTextAlignment(.center)
          }
      }
      
      struct ContentView_Previews: PreviewProvider {
          static var previews: some View {
              ContentView()
                  .environment(\.locale, Locale(identifier: "en_US"))
              ContentView()
                  .environment(\.locale, Locale(identifier: "he_IL"))
              ContentView()
                  .environment(\.locale, Locale(identifier: "es_ES"))
          }
      }
    • 23:53 - Parsing Dates

      func parsingDates() {
          let date = Date.now
      
          let format = Date.FormatStyle().year().day().month()
          let formatted = date.formatted(format)
          // example: "Jun 7, 2021"
          print(formatted)
      
          if let date = try? Date(formatted, strategy: format) {
              // example: 2021-06-07 07:00:00 +0000
              print(date)
          }
      }
    • 24:23 - Parsing Dates - Strategies

      func parsingDatesStrategies() {
          let strategy = Date.ParseStrategy(
              format: "\(year: .defaultDigits)-\(month: .twoDigits)-\(day: .twoDigits)",
              timeZone: TimeZone.current)
      
          if let date = try? Date("2021-06-07", strategy: strategy) {
              // date is 2021-06-07 07:00:00 +0000
              print(date)
          }
      }
    • 25:30 - Formatting Numbers

      func formattingNumbers() {
          // Note: This will use your current locale. Example output is for en_US locale.
          let value = 12345
      
          let formatted = value.formatted()
          // formatted is "12,345"
          print(formatted)
      }
    • 25:36 - Formatting Numbers With Styles

      func formattingNumbersWithStyles() {
          // Note: This will use your current locale. Example output is for en_US locale.
          let percent = 25
          let percentFormatted = percent.formatted(.percent)
          // percentFormatted is "25%"
          print(percentFormatted)
      
          let scientific = 42e9
          let scientificFormatted = scientific.formatted(.number.notation(.scientific))
          // scientificFormatted is "4.2E10"
          print(scientificFormatted)
      
          let price = 29
          let priceFormatted = price.formatted(.currency(code: "usd"))
          // priceFormatted is "$29.00"
          print(priceFormatted)
      }
    • 25:47 - Formatting Lists

      func formattingLists() {
          // Note: This will use your current locale. Example output is for en_US locale.
          let list = [25, 50, 75].formatted(.list(memberStyle: .percent, type: .or))
          // list is "25%, 50%, or 75%"
          print(list)
      }
    • 26:05 - Receipt Tip View

      struct ReceiptTipView: View {
          @State var tip = 0.15
      
          var body: some View {
              HStack {
                  Text("Tip")
                  Spacer()
                  TextField("Amount",
                            value: $tip,
                            format: .percent)
              }
          }
      }
    • 29:41 - Automatic Grammar Agreement

      func addToOrderEnglish() {
          // Note: This will use your current locale. Example output is for en_US locale.
          let quantity = 2
          let size = "large"
          let food = "salad"
      
          let message = AttributedString(localized: "Add ^[\(quantity) \(size) \(food)](inflect: true) to your order")
          print(message)
      }

Developer Footer

  • Videos
  • WWDC21
  • What's new in Foundation
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines