View in English

  • 메뉴 열기 메뉴 닫기
  • Apple Developer
검색
검색 닫기
  • Apple Developer
  • 뉴스
  • 둘러보기
  • 디자인
  • 개발
  • 배포
  • 지원
  • 계정
페이지에서만 검색

빠른 링크

5 빠른 링크

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 주제
  • 전체 비디오
  • 소개

더 많은 비디오

스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.

  • 소개
  • 요약
  • 자막 전문
  • 코드
  • Swift의 새로운 기능

    Swift의 최신 업데이트를 알아보세요. 생산성을 높여주는 워크플로 개선 사항과 기본적인 프로그래밍 작업에 대한 새롭고 현대화된 라이브러리 API를 소개합니다. 마지막으로 동시성에 대한 접근성을 개선하고 필요할 때 최적의 성능을 달성하는 새로운 언어 기능을 살펴봅니다.

    챕터

    • 0:00 - Introduction & Agenda
    • 0:48 - swiftlang updates
    • 3:06 - Development workflow: Writing code
    • 4:40 - Development workflow: Building
    • 7:36 - Development workflow: Debugging
    • 9:14 - Libraries: Subprocess
    • 10:45 - Libraries: Foundation
    • 12:31 - Libraries: Observation
    • 14:13 - Libraries: Testing
    • 16:08 - Swift throughout the stack: Embedded Swift
    • 18:00 - Swift throughout the stack: Security
    • 19:37 - Swift throughout the stack: Server
    • 23:23 - Swift throughout the stack: Platforms
    • 26:11 - Language evolution: Performance
    • 30:28 - Language evolution: Concurrency
    • 37:15 - Wrap up

    리소스

    • The Swift Programming Language
    • The Swift website
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC25

    • 컨테이너화 만나보기
    • 코딩 실습: Swift 동시성으로 앱 수준 높이기
    • C, C++, Swift를 안전하게 함께 사용하기
    • Swift 동시성 사용하기
    • Swift 및 Java 상호운용성 살펴보기
    • Swift로 메모리 사용량 및 성능 개선하기

    WWDC24

    • 명시적으로 빌드된 모듈 쉽게 이해하기
    • Embedded Swift로 경량화하기
    • Swift의 성능 살펴보기
  • 비디오 검색…

    안녕하세요, What's New in Swift에 잘 오셨습니다 저는 Holly입니다 그리고 저는 Allan입니다 오늘은 Swift 6.2의 새로운 기능과 개선점을 보여드리겠습니다 여러분을 더 생산적인 Swift 프로그래머로 만들어줄 개선점이죠 어디에서 어떤 종류의 코드를 작성하든 상관 없습니다 먼저 코드 작성, 빌드, 디버깅 워크플로 개선점에 대해 알아보겠습니다 또한 기본 프로그래밍 작업을 위한 새 라이브러리 API를 살펴봅니다 소프트웨어 스택의 각 레이어에 Swift를 채택하는 방법도 보여드리겠습니다 마지막으로, 필요할 때 최고의 성능을 내도록 동시성을 향상시켜줄 새 언어 기능을 살펴보겠습니다 오늘 다룰 모든 변경 사항은 오픈 소스에서 함께 개발했습니다 GitHub의 Swift Lang 조직은 50개가 넘는 프로젝트로 성장했고 컴파일러, swift.org 웹사이트 기본 라이브러리와 테스팅 라이브러리 및 더 큰 생태계를 이루는 여타 주요 구성 요소를 포함하고 있습니다 프로젝트를 Swiftlang으로 마이그레이션하는 것 외에도 Swift Build라는 Xcode 빌드 시스템을 오픈 소스로 공유했죠 Swift Build는 Apple 운영체제를 위한 빌드 프로세스를 지원합니다 오픈 소스에서는 Swift Build를 Swift 패키지 관리자의 로우 레벨 빌드 시스템으로 채택하는 적극적 움직임이 있었죠 swift.org 도구 체인과 Xcode 간의 빌드 엔진을 통합할 움직임이죠 Swift Build에 대해서는 'Swift Build 기술의 다음 장' 블로그 게시물에서 읽을 수 있죠 Swiftlang 프로젝트의 새 멤버 중에는 Swiftly라는 버전 관리자가 있습니다 Swiftly는 원래 Linux상 Swift 도구 체인 관리를 간소화하기 위해 오픈 소스 커뮤니티에서 개발한 것입니다 이제 Swiftly는 macOS를 지원합니다 swift.org에서 1.0 릴리즈를 만나보세요 명령 하나로 최신 Swift 툴체인을 설치하거나 GitHub 브랜치에서 야간 스냅샷을 설치하여 개발 중인 언어 기능을 사용해 볼 수 있습니다 Xcode에서 Swiftly가 설치한 툴체인은 툴체인 메뉴에서 사용할 수 있습니다 앱을 빌드하는 경우에도 Xcode 툴체인을 사용하여 App Store에 제출해야 합니다 VS Code에서는 툴체인 명령에서 Swiftly가 설치한 툴체인을 선택할 수 있습니다 Swift 블로그에서 Swiftly 1.0에 대해 알아보세요 Swift를 툴을 다운로드하는 것 이외의 용도로 활용할 수 있는 개선점입니다 새 단장을 한 Swift.org 홈페이지는 앱과 클라우드 서비스부터 임베디드 시스템에 이르기까지 다양한 주제에 빠져들 수 있도록 새롭게 구성되었습니다 이 작업은 Swift 웹사이트 작업 그룹과 협력합니다 Swift를 시작하는 것이 그 어느 때보다 쉬워졌습니다 Allan이 Swift 6.2를 통해 어떻게 유연한 개발 환경을 조성할 수 있는지 보여드릴 것입니다 고마워요 Holly 올해 Swift 릴리즈에는 수많은 개발 워크플로 개선점이 포함되어 있습니다 Swift 코드를 어떻게 쓰시든 반드시 도움이 되실 것입니다 이 개선점은 코드 작성부터 빌드와 디버깅에 이르기까지 다양한 워크플로에 적용됩니다 VS 코드에서 개발하신다면 올해 새로운 내용이 무엇인지 살펴보는 것부터 시작해보죠

    VS 코드 마켓플레이스의 Swift 확장 프로그램은 이제 공식 인증을 받아 swift.org를 통해 배포됩니다 지난 한 해 동안 새로운 기능도 다수 추가 되었습니다 첫 번째는 백그라운드 인덱싱입니다 Swift 6.1에서는 VS Code 및 다른 IDE상의 Swift PM 프로젝트 기본값으로서 백그라운드 인덱싱이 활성화됩니다 이는 정의로 이동과 같은 편집기 기능을 가능하게 해 새로운 프로젝트 변경사항도 추적할 수 있게 해줍니다 SourceKit-LSP 개선점 덕분에 이제 VS Code 코드 완성 기능의 관련성이 더 높아졌습니다 디버깅 또한 단순화되었습니다 이제 Swift 확장 프로그램 설치 시 LLDB 지원이 자동으로 포함됩니다 최신 버전의 확장 프로그램에는 새 프로젝트 패널도 포함되어 패키지의 종속성, 대상 및 작업을 쉽게 찾을 수 있습니다 마지막으로, VS Code Swift 확장 프로그램은 프로젝트 문서를 볼 수 있는 새로운 방법 또한 선사합니다 DocC 미리보기를 코드와 나란히 두고서 입력과 동시에 실시간으로 확인할 수 있습니다 VS Code Swift 확장 프로그램은 오픈 소스로 개발되었으며 swiftlang 조직 GitHub에서 찾을 수 있습니다 이제 어디서든 사용이 가능한 Swift 코드를 구축하는 몇 가지 개선점에 대해 이야기해 봅시다 생산성에 있어 중요한 한 가지는 도구의 성능입니다

    Swift 6.2는 매크로 기반 API를 사용하는 프로젝트의 클린 빌드 시간을 크게 개선합니다 보여드리자면, Stringify라는 패키지의 매크로를 사용하는 프로젝트가 있다고 가정해봅시다 이전에는 프로젝트를 구축하기 위해 Swift PM이 먼저 매크로를 지원하는 라이브러리인 Swift Syntax의 소스를 가져와야 했습니다 그런 다음 Swift Syntax, Stringify 매크로 플러그인 코드를 순서로 구축했습니다 구축된 Swift Syntax는 캐시가 가능했지만 클린 빌드에 필요한 시간이 더 들었습니다 이는 지속적인 통합 환경에서 특히 눈에 띄는 차이입니다 구축 속도를 높이기 위해 Swift PM 및 Xcode의 최신 릴리즈는 사전 구축된 Swift 구문 종속성을 지원합니다 이는 무거운 구축 단계를 완전히 없애고 일부 프로젝트의 경우 빌드 시간을 몇 분이나 줄여줍니다

    매크로를 제공하는 패키지를 직접 보유하고 있다면 패키지가 Swift Syntax의 태그된 릴리즈에 의존하는 한 고객이 최적화의 이점을 누릴 수 있습니다 하지만 생산성은 빌드 성능에 의해서만 좌우되지 않죠 때로는 컴파일러가 발견한 문제를 해결하느라 늦어질 수 있습니다 예를 들어 Swift 6 언어 모드에서 동시 코드를 작성할 때 컴파일러가 방지해야 할 잠재적인 데이터 경쟁을 감지할 수 있습니다 중요한 사안을 식별한 오류임에도 해결법은 모호할 수 있습니다 그래서 Swift 6.2에서는 다양한 진단 카테고리를 다루도록 문서를 늘렸습니다 일반적인 경고와 오류에 대한 설명을 제공하기 때문에 문제를 이해하고 견고한 해결법을 찾을 수 있도록 도와줍니다 문서는 IDE와 swift.org에서 온라인으로 액세스할 수 있습니다 진단의 작동 방식을 제어하는 것도 중요할 수 있습니다 예를 들어, 코드에서 경고를 없애려면 '오류로 경고' 설정을 사용할 수 있습니다 이는 해결하기 쉬운 경고에는 잘 듣지만 더 이상 사용되지 않는 API와 같은 경고에는 즉시 적용하지 않는 것이 좋을 수 있습니다 Swift 6.2는 원하는 경고를 오류로서 취급할 수 있는 유연성을 제공합니다 예를 들어, 모든 경고를 오류로 처리하는 것을 기본값으로 두고 더 이상 사용되지 않는 선언은 예외로 둘 수 있습니다 반면에, 단순히 일부 경고 카테고리를 방지하고자 한다면 대신 해당 경고를 오류로 승격할 수 있습니다 컴파일러 경고에 대한 제어 기능을 추가한 것은 커뮤니티의 주도로 Swift를 개선해 모든 개발자가 이점을 누린 좋은 예가 되었습니다 포럼 토론의 장에 제안을 올린 작성자와 토론에 참여한 모든 분들께 감사드립니다 끝으로, 훌륭한 Swift 6.2 디버깅 여러 개선점을 살펴보겠습니다

    이번 릴리즈에서는 비동기 코드 디버깅 경험이 크게 개선되었습니다 Swift 작업에서 실행되는 코드를 살펴보면 이제 LLDB가 스레드 간의 전환이 필요한 경우에도 비동기 함수 실행을 따라가는 것을 볼 수 있습니다 디버거가 Swift 작업 중심 모델을 어떻게 이해하는지에 따라 이로 하여금 어떤 작업이 실행되는지가 나타납니다 쉽게 식별할 수 있도록 작업의 이름을 지정할 수도 있죠 작업 이름 또한 기기 동시성 프로필에 기록된 기기 프로필에 나타납니다 또한 Swift 작업 정보와 같은 새 명령을 사용해 우선 작업과 하위 작업과 같이 현재 실행 중인 작업에 대한 정보를 더 얻을 수도 있습니다 마지막으로, 올해 디버깅 세션 반응성이 더 개선되었습니다 명시적으로 빌드된 모듈 덕분이죠 빌드 모듈은 모듈 종속성 빌드 시 병렬 처리 및 재사용을 가능하게 하는 빌드 시스템 기능입니다 명시적으로 빌드된 모듈 이전에 Xcode 빌드 및 디버거는 완전히 분리된 모듈 그래프를 사용해야 했습니다 이제 디버거는 빌드의 모듈을 재사용할 수 있습니다 즉, 디버거에서 P 또는 PO를 처음 실행할 때 명령이 평가를 훨씬 빠르게 처리합니다 유형 정보가 즉각적으로 제공되기 때문이죠 명시적으로 빌드된 모듈은 Xcode 26에서 기본 활성화됩니다 올해 Swift 도구 개선점 중 일부에 불과하죠 다음으로, 매일 사용하는 핵심 Swift 라이브러리에 대한 몇 가지 중요한 업데이트를 살펴보겠습니다 라이브러리는 정말 다양한 작업을 도와줍니다 Swift의 핵심 라이브러리는 Swift 코드 작성에 매우 중요한 요소죠 Swift 6.2는 Foundation API 표면을 더 현대화하고 간소화하는 새로운 API를 제공합니다 Swift를 작성 작업에 사용하는 경험을 개선하기 위해 Foundation 작업 그룹은 하위 프로세스를 도입했습니다 먼저 새 하위 프로세스 패키지를 추가하고 가져오는 것으로 시작해 실행 함수 호출 및 결과 대기 후 하위 프로세스를 시작합니다 프로세스 이름이 포함된 문자열을 제공하면 실행 메서드가 $PATH 환경 변수에 기반하여 실행 파일을 조회합니다

    대부분의 경우, 파일 경로를 통해 하위 프로세스를 시작하여 실행 파일까지의 전체 경로를 식별합니다 하위 프로세스가 종료되면 종료 상태, 표준 출력 및 프로세스 실행에 대한 다른 정보를 검토할 수 있습니다 하위 프로세스 라이브러리에는 실행, 플랫폼별 구성 옵션 등 프로세스를 더 세밀히 제어하는 더 많은 기능이 있습니다 Swift 하위 프로세스 저장소에서 전체 API 표면을 탐색해보세요 패키지는 버전 0.1에 있으며 채택에 대한 피드백은 버전 1.0에 릴리즈된 API에 알려집니다 Foundation 작업 그룹은 앱 프로젝트에서 매일 같이 사용하는 API도 개선했습니다 UIKit의 알림에 응답하는 것은 iOS 앱에서 일반적인 동작이지만 이 알림을 관찰할 코드에는 오류가 빈번하게 발생합니다 먼저 객체가 게시를 지원하는 알림 이름을 등록할 때에는 조심해야 합니다 실수하면 알림 호출이 실행되지 않기 때문입니다 알림에 대한 정보는 유형이 지정되지 않은 사전에 저장되며 이 사전에는 올바른 키를 사용해 아래 첨자 기호를 추가하고 올바른 유형에 맞게 결과를 동적으로 변환해야 합니다 알림이 메인 스레드에 게시하는 것이 보장되더라도 MainActor API에 접근할 때 동시성 오류가 나타날 수 있습니다 알림 이름과 페이로드는 이제 구체적인 유형을 지원합니다 구체적인 유형은 컴파일러로 하여금 등록하려는 알림을 지원하는 객체를 확인하도록 허용합니다 또한 알림 페이로드로 작업할 때 보일러 플레이트를 제거합니다 알림 유형은 알림이 게시된 위치를 지정합니다 MainActor API에는 MainActor에 알림이 게시되면 자유롭게 접근할 수 있습니다 MainActor 메시지에 대한 적합성은 알림이 항상 메인 스레드에 동기적으로 게시되도록 보장합니다 비동기 메시지에 대한 적합성은 알림이 임의의 스레드에 비동기적으로 게시되는 것을 의미합니다 구체적인 알림 유형은 UIKIT 및 Foundation이 게시한 알림에 대한 SDK에서 볼 수 있습니다 또한 자체 알림에 대해 구체적인 알림 유형을 추가할 수도 있습니다 등록된 옵저버에 대한 브로드캐스트 시스템 알림은 보다 일반적인 옵저버 패턴을 기반으로 합니다 관찰 라이브러리는 객체 그래프의 상태 변화를 자동으로 추적하는 범용 API를 제공합니다

    관찰 추적에서 @Observable 매크로를 사용해 클래스를 선택할 수 있습니다 Swift 6.2는 관찰 가능한 유형의 AsyncSequence로 상태 변경을 스트리밍하는 방법을 도입합니다 클로저가 있는 새로운 관찰 유형의 인스턴스를 생성하는 것으로 시작합니다 클로저에서는 변경 사항을 관찰하려는 값을 계산합니다 플레이어의 현 상태를 설명하는 문자열을 관찰하고 싶습니다 점수 업데이트나 새 아이템 획득 시 새로운 값이 클로저에 사용된 관찰 가능한 속성을 기반으로 업데이트된 값을 얻을 수 있습니다 업데이트는 거래에 따라 발생합니다 업데이트 추적은 클로저의 관찰 가능한 속성에 willSet이 호출될 때 시작됩니다 이는 다음 대기 시 코드가 중단될 때 끝납니다 업데이트된 값에는 코드의 두 지점 사이에 다른 속성에 대한 모든 동기 변경 사항이 포함됩니다 이렇게 하면 여러 속성에 대한 동기 업데이트가 발생해도 일관성 없는 객체에 관찰 업데이트가 전달되지 않습니다

    점수와 항목을 모두 동기적으로 업데이트하면 두 변경 사항을 모두 포함한 업데이트 값 한 개만 얻게 됩니다 관찰 유형은 AsyncSequence를 준수하므로 for-await 루프를 사용해 업데이트된 값을 반복할 수 있죠 개발자들은 매일 테스트하는 것이 일입니다 Swift Testing은 테스트 설명 및 정리용 매크로를 제공하는 크로스 플랫폼 라이브러리입니다 테스트 함수를 선언하는 @test 속성과 같죠 가정 검증을 위해 매크로를 기대 및 요구하게 되는데 Swift Testing은 기대 또는 요구가 실패할 경우, 조치를 취할 수 있는 정보를 줍니다 때로는 테스트에 실패했는지 선별하기 어려울 수 있습니다 특히 CI와 같은 원격 환경에서만 실패하는 경우 더 그렇습니다 테스트 실패를 이해하려면 테스트에 사용된 데이터에 대한 맥락이 더 필요합니다

    Swift 6.2는 테스트 실패 진단에 사용자 지정 첨부 파일을 도입하죠 Attachment.record 메서드 호출로 테스트에 첨부 파일을 추가합니다 데이터와 문자열과 같은 라이브러리 유형을 첨부할 수 있고 첨부 가능한 프로토콜을 준수하는 것으로 자체 유형을 지원하는 첨부 파일도 구현할 수 있습니다 Swift 6.2는 또한 종료 테스트를 지원하여 특정 조건하에 종료하려는 코드를 테스트할 수 있도록 해주죠 예를 들어, 전제 조건을 통해 입력 매개 변수에 대한 가정을 검증하는 함수를 작성할 때 전제 조건이 충족되지 않으면 성공하는 테스트 케이스를 작성할 수 있죠

    #expect 또는 #required에 processExitsWith 인수를 전달하여 종료 테스트를 작성합니다 종료 테스트 작성 시 Swift Testing에서 새 테스트 실행 프로세스를 사용할 수 있습니다 특정 종료 코드나 시그널과 함께 프로세스가 성공적으로 종료됐는지 해당하는 경우, 실패 상태로 종료됐는지 검증할 수 있습니다 이러한 범용 라이브러리 사용 시 애플리케이션 코드 외에도 프로젝트에서 이식 가능한 Swift 코드 작성 및 테스트를 할 수 있죠 Apple에서는 전체 소프트웨어 스택에서 Swift를 사용합니다 펌웨어, 앱 및 프레임워크 대규모 웹 서비스에 사용합니다 임베디드 장치, 보안에 중요한 구성 요소 및 서버에 대한 코드를 작성할 때 Swift 6.2의 개선점의 이점을 누려보세요 몇 가지 새로운 플랫폼도 타깃팅할 수 있을 것입니다 Embedded Swift로 스택의 하단부터 시작하겠습니다 Embedded Swift는 매우 제약적인 환경을 타깃으로 코드를 작성할 수 있게 해주는 Swift의 하위 집합입니다 임베디드 디바이스 펌웨어 또는 운영체제 커널과 같은 환경 말이죠 값 및 참조 유형, 클로저, 옵션 오류 처리, 제네릭 등 핵심 Swift 기능을 지원하는 컴파일 모드입니다 Apple에서는 iPhone에서 실행되는 가장 낮은 수준의 소프트웨어에서 Embedded Swift를 사용합니다 예를 들어, iOS 26에서 Embedded Swift는 CPU와 GPU 사이의 공유 메모리 페이지에 대한 접근을 관리하는 보조 프로세서에서 실행됩니다 Embedded Swift를 사용하려면 '임베디드로 경량화하기'를 시청해 더 많은 것을 배워보세요 Swift 6.2는 Embedded Swift에 새로운 역량을 불어 넣었습니다 이제 문자열 보간을 포함하여 Swift의 전체 문자열 API를 다루죠 이제 프로토콜을 준수하는 유형의 값을 나타낼 수 있는 Swift의 모든 유형 기능 또한 프로토콜이 클래스 유형의 제약을 받을 때 사용할 수 있습니다 Swift 표준 라이브러리 또한 InlineArray 및 Span을 게인합니다 두 메모리 영역에서 효율적으로 작업 가능한 두 가지 새 API죠 Holly가 나중에 더 자세히 다룰 유형으로, 임베디드 프로그램에서 종종 볼 수 있듯 성능에 민감한 코드와 같은 종류에 매우 적합합니다 Embedded Swift가 강력해짐에 따라 다들 나만의 임베디드 프로젝트를 시작할 수 있는 예시를 바쁘게 만들어내기 시작했습니다 GitHub의 Swift Embedded Examples 저장소에서 확인해 보세요 Embedded Swift의 한 가지 이점은 메모리가 안전한 환경에서 낮은 수준의 소프트웨어를 작성할 수 있다는 점입니다 메모리 안전 코드는 보다 안전하죠 Apple은 Swift를 철저한 보안에 발맞춘 코드로 만들기 위해 노력해왔습니다 가끔은 근본적으로 안전하지 않은 작업을 위해서도 코드를 작성하기 마련입니다 예를 들어, C로 작성된 종속성과 통합할 때에는 포인터를 수용하는 API를 사용하는 것이 일반적인 것에 반해 보안이 중요한 상황에서 안전하지 않은 코드는 최대한 피해야 하죠 이를 피할 수 없다면 적어도 식별이 쉽도록 만들어야 합니다 그래서 Swift 6.2는 철저한 메모리 안전이라는 *옵트인* 기능을 새로 탑재했습니다 이 모드는 안전하지 않은 API의 모든 사용을 소스에서 명시적으로 인정해야 합니다 모드에 필요한 주석은 보안을 위해 어떤 코드 부분이 추가로 필요한지 식별하는 데 도움이 됩니다 이 새로운 모드와 더불어 Swift 6.2는 Span과 같이 안전한 어고노믹 유형을 통해 Swift에 API를 불러오는 C 및 C++ 헤더에 대한 새로운 주석도 지원합니다 새로운 상호운용성 기능에 대해 더 알아보려면 'C, C++, Swift를 안전하게 함께 사용하기'를 살펴보세요 Apple 운영체제에서는 Webkit와 수신 메시지, 첨부 파일을 파싱하는 메시지 앱의 하위 시스템이라는 두 가지 보안이 중요한 구성 요소에 철저한 메모리 안전을 도입합니다 두 요소 모두 신뢰할 수 없는 입력을 처리하기 때문에 안전하지 않은 API의 사용 제한에 특히 중요합니다 이제 서버 생태계에서 Swift가 사용되고 있는 방식을 살펴 보죠

    Swift는 Apple의 서비스에서 중요한 역할을 합니다 매초 수백만 건의 요청이 Swift로 구동되는 백엔드 서비스를 통해 처리됩니다 그중 하나는 데이터 침해 발생 시 침해된 것으로 발견된 암호에 대해 사용자에게 경고하는 역할을 합니다 이전에 Java로 구축된 이 서비스는 최근에 Swift로 다시 작성된 후 큰 이점을 선사했습니다 Swift의 효율적인 네이티브 코드와 결정론적 메모리 관리 덕분에 서비스 처리량이 40% 늘어나고 하드웨어 요구 사항이 절반으로 줄었습니다

    많이들 서버에 Swift를 도입해 이점을 누리고 있습니다 예를 들어 Cultured Code 엔지니어들이 Things Cloud라는 유명 앱, Things 앱을 백엔드에서 Swift로 재구현한 경험을 swift.org에 공유한 바 있습니다

    Things Cloud의 경우 Swift를 통해 컴퓨팅 비용을 3배 절감하고 평균 응답 시간을 400%나 개선할 수 있었습니다 향상된 성능 외, Swift를 채택한 또 다른 이점으로는 클라이언트와 서버 개발에서 같은 언어와 도구를 쓸 수 있다는 점이 있었습니다 팀이 Swift로 서버 백엔드를 구축하는 데 기여하는 핵심은 라이브러리입니다 Swift는 매우 다양한 필수 사용 사례의 패키지 생태계를 보유하고 있으며 이는 확장을 거듭하고 있습니다 네트워킹, 데이터베이스 드라이버 관찰 가능성 메시지 스트리밍 등을 위한 라이브러리입니다 올해 눈에 띄는 업데이트는 gRPC Swift 버전 2 릴리즈였습니다 gRPC는 서비스 API 구축을 위한 현대적인 고성능 패키지입니다 버전 2의 하이라이트는 Swift 동시성 관용적 생성 스위프트 코드 플러그 가능한 고성능 전송 계층을 활용하는 현대화된 API입니다 gRPC Swift의 관리자가 Swift.org 업데이트에 대해 작성한 블로그 게시물을 확인해보세요 C, Objective-C, C++와의 상호운용성은 Swift의 핵심 강점 중 하나입니다 이러한 언어로 작성된 기존 코드 베이스는 한 번에 한 파일씩 Swift를 도입해 점진적으로 개선할 수 있습니다 서버 생태계의 기존 앱은 대부분 Java로 작성되었습니다 이러한 코드베이스에도 점진적인 Swift 채택이 주는 가능성이 크다고 생각합니다 따라서 작년에는 Swift Java라는 흥미진진한 새로운 오픈 소스 프로젝트를 발표했습니다 언어가 원활하게 상호 운용되도록 하는 것을 목표로 하죠

    Swift-Java는 Swift 코드와 Java 코드가 서로 호출하도록 바인딩을 생성할 수 있습니다 이러한 바인딩은 과도한 오버헤드 없이도 각 언어에서 얻은 값의 네이티브 표현을 래핑하도록 설계되었습니다 Swift 코드에 대한 Java 바인딩은 Java의 차세대 외부 인터페이스 기술을 사용하거나, 필요한 경우 JNI로 폴백할 수 있습니다 Swift-Java 프로젝트는 현재 실험 중이며 빠르게 진화하고 있습니다 사용 방법을 더 배우고 싶다면 'Swift 및 Java 상호운용성 살펴보기'를 시청하세요

    클라이언트와 서버 구성 요소가 모두 있는 앱 작업 시 두 환경에서 코드를 로컬 테스트하는 워크플로가 필요합니다 Apple은 Mac에서 실행하는 Linux 컨테이너 기반 도구 구축 시 사용하는 새로운 오픈 소스 컨테이너화 라이브러리를 릴리즈합니다 이는 완전히 Swift로 구현되었고 보안, 개인정보 보호 및 성능에 중점을 두고 설계되었습니다 시스템 수준 개발에 Swift를 사용한 좋은 예입니다 이 라이브러리의 자세한 정보는 '컨테이너화 만나보기'를 보세요 GitHub에서 컨테이너화 저장소에서 명령줄 바이너리를 찾아 컨테이너를 실행해보세요 마지막으로, Swift가 지원하는 플랫폼에 대한 업데이트입니다 Swift 6.2에는 서버와 임베디드 플랫폼에서 인기 있는 운영체제인 FreeBSD에 대한 공식 지원이 추가되었습니다 또한 Swift는 Wasm이라고 하는 WebAssembly의 지원을 받고 있죠 WebAssembly는 이동성, 보안 및 고성능에 초점을 맞춘 가상 머신 플랫폼입니다 개발자는 Wasm용 클라이언트 및 서버 어플리케이션을 구축한 후 브라우저 또는 다른 런타임에 이를 배포할 수 있습니다 WebAssembly 지원은 커뮤니티 프로젝트로 시작되었죠 올해 초, 그 프로젝트는 Swift의 공식 WebAssembly 지원을 위한 비전 문서와 함께 중요한 이정표를 세웠습니다 Wasm 지원은 실제로 어떤지 확인해 봅시다 Swift로 작성된 앱이 있습니다 파일에서 3D 모델을 로드 후 브라우저에서 렌더링하는 앱입니다 앱의 현 모습은 다음과 같습니다

    앱은 Wasm 가상 머신에서 실행되며 Swift 로고는 WebGPU라는 실험적 웹 스탠다드를 사용해 렌더링된 것입니다

    이 앱은 SwiftWasm 조직이 개발한 오픈 소스 패키지인 JavascriptKit를 사용합니다 이 라이브러리를 사용해 네이티브 Swift API로 JavaScript 런타임과 상호작용할 수 있습니다 최종 바이너리를 최대한 컴팩트하게 만들기 위해 Embedded Swift로 앱을 컴파일링하겠습니다 하지만 대부분 이 코드는 그냥 일반적인 Swift 코드입니다

    제네릭으로 지오메트리 유틸리티를 몇 개 추가하는 것처럼요 Wavefront 객체 파일 파서는 Swift의 기본 문자열 API 사용 파서입니다

    애니메이션을 좀 추가해 봅시다 이제 렌더러의 업데이트 방법으로 넘어가겠습니다

    모델을 살짝 뒤틀어보자면 로고의 회전은 각 프레임에서 업데이트되어야 합니다

    테스트해보겠습니다 애플리케이션을 재실행하고자 프로젝트 패널에서 작업을 트리거했습니다 SwiftBuild를 호출해 WASM 앱을 컴파일하도록 구성되었죠 그 다음 빌드한 출력값에서 최소화 도구를 몇 개 실행해 바이너리를 최대한 작게 만듭니다 마지막으로 콘텐츠 호스팅을 위해 웹 서버를 시작합니다 다 좋아 보이네요 소프트웨어 스택 전반에서 Swift가 좋은 선택지인 이유는 바로 좋은 언어이기 때문입니다 Swift는 기본적으로 안전과 쉬운 사용성을 우선시하면서 훈련된 프로그래머들에게 복잡한 코드를 작성하고 최대 성능을 위해 조정할 수 있는 도구를 제공합니다 필요하다면 언어 특성에 대하여도 알아볼 수 있습니다 먼저 작게 시작해보고 준비가 되면 고급 기능을 알아보세요

    Swift 6.2는 언어를 발전시켜 초보자와 전문가 모두가 더 쉽게 사용할 수 있도록 합니다 보다 쉽게 프로젝트에 동시성을 도입하는 방법을 제공합니다 성능에 중요한 코드를 작성하는 전문가들이 이 언어를 더 강력하게 만들었죠 성능 업데이트부터 시작하겠습니다 배열 유형은 정렬된 요소 목록이며 Swift 프로젝트에서 가장 일반적으로 사용되는 데이터 유형에 속합니다 동적 크기 조정과 같은 배열의 기능은 사용하기 쉬우며 다양한 작업에 적합합니다 그러나 유연성에는 대가가 따르죠 동적 크기 조정을 지원하기 위해 배열은 힙 할당 버퍼에 대한 참조를 저장합니다 더 많은 요소가 추가되고 배열이 용량에 도달하면 동적으로 새 메모리를 할당하고 기존 요소들을 복사해야 합니다 핫 경로에서 배열을 사용하는 성능에 중요한 코드 프로파일링 시 제거해야 하는 배열 버퍼에 대한 메모리 할당 또는 참조 계산을 보시게 될 수 있습니다 배열의 크기가 변하지 않으면 힙 할당 비용을 지불할 필요가 없습니다 InlineArray는 요소를 위한 인라인 스토리지가 있는 새로운 고정 크기 배열 유형입니다 크기는 요소 유형 앞의 꺾쇠 괄호 안에 작성된 유형의 일부입니다

    요소를 포함하는 버퍼에 대한 참조를 저장하는 대신 InlineArray의 요소는 바로 저장됩니다 이는 요소가 스택에 저장되거나 추가 힙 할당 없이 다른 유형 내에 직접 저장될 수 있음을 의미합니다 InlineArray에는 복사 가능한 유형 및 불가능한 유형을 저장합니다 복사 가능한 유형을 저장할 때에는 InlineArray를 복사할 수 있으며 요소 값은 열심히 복사됩니다 정수를 유형 매개 변수로 허용하는 새로운 제네릭 기능을 사용하여 유형의 일부로 크기를 작성합니다 요소 유형과 마찬가지로 InlineArray의 크기는 배열 리터럴에서 추론할 수 있습니다 1, 2, 3의 InlineArray을 작성하면 유형은 정수 3개로 된 InlineArray로 추론됩니다 컴파일 시점의 InlineArray 크기를 알면 인덱스가 크기보다 작을 때 경계를 확인하지 않아도 되는 등 더 많은 최적화가 가능합니다 컨테이너 유형은 기본 저장소에 직접 접근해야 할 때가 많습니다 원래 컨테이너의 레이아웃을 알 필요 없이 연속 메모리에서 로컬 처리를 수행하는 데 유용합니다 예를 들어 함수가 인접한 스토리지에서 직접 작동하도록 허용하려면 Swift 6.2 이전에는 일반적으로 안전하지 않은 포인터를 사용해야 했습니다 이는 근본적으로 안전하지 않고 실수하기 쉬운 방법이죠

    새로운 Span 유형은 메모리 안전을 저해하지 않으면서도 연속 메모리에 대해 빠르고 직접적인 접근을 제공하는 추상화입니다 표준 라이브러리는 연속적인 저장 공간이 있는 모든 컨테이너 유형에 대해 span 속성을 제공합니다 Array, ArraySlice InlineArray 등 그 요소를 위한 것이죠

    Span을 사용하는 내내 연속 메모리가 유효하도록 메모리 안전을 유지합니다 이렇게 하면 무료 이후 사용과 중복 수정을 포함해 포인터에 내재된 메모리 안전 문제를 정의에서 배제할 수 있습니다 이는 런타임 오버헤드 없이 컴파일 시 점검됩니다 예를 들어, 원래 컨테이너를 수정하면 추후 span에 대한 접근을 방지하게 됩니다 수정 후에는 span 변수에 다시 접근할 수 없습니다

    span은 또한 원래 컨테이너를 능가할 수 없습니다 이를 평생 종속성이라고 하며 span을 통해 기본 스토리지에 대한 접근이 가능하면서도 삭제되지 않도록 예방합니다 InlineArray 및 span의 성능을 제어하는 새로운 방법을 배우려면 'Swift로 메모리 사용량 및 성능 개선하기'를 시청하세요 Swift 코드의 성능 특성을 이해하는 방법에 대해 더 알아보려면 'Swift 성능 살펴보기'를 보세요

    성능에서 중요한 또 다른 측면은 프로그램이 여러 작업을 수행해야 할 때의 응답성입니다 동시 프로그래밍은 여러 작업 간에 메모리를 공유하기 때문에 실수에 취약해 예상치 못한 결과로 이어질 수 있어 어렵습니다 Swift 6의 데이터 레이 안전은 컴파일에서의 실수를 예방해 디버깅이 어려운 런타임 버그 걱정 없이 동시 코드를 작성할 수 있도록 합니다 하지만 대부분, 작성하기에 가장 자연스러운 코드는 데이터 레이스에 취약하여 컴파일러 오류로 이어져 해결이 필요합니다 이 PhotoProcessor 클래스와 같이 가변 상태를 가진 클래스는 동시에 접근하지 않는 한 안전합니다 여기에는 주어진 이미지 데이터의 주제를 계산함으로써 스티커를 추출하는 비동기 방법을 사용할 수 있습니다 하지만 MainActor에 UI 코드의 extractSticker를 호출하려고 하면 오류가 발생해 데이터 레이스로 이어질 위험이 있습니다 이것은 병렬 실행을 위한 코드가 필요 없더라도 언어에 암시적으로 작업을 백그라운드에서 오프로드하는 지점이 여러 개이기 때문입니다

    Swift 6.2는 이 개념을 바꾸어 동시성 도입을 결정하기 전까지 기본적으로 단일 스레드를 유지합니다

    언어 변경 덕에 Swift 6.2 사용 시 기본적으로 데이터 레이스 없이도 가장 자연스러운 코드를 작성할 수 있습니다 프로젝트에 동시성을 도입하는 더 쉬운 경로를 제공합니다 코드를 병렬로 실행하고자 동시성을 도입하기로 선택하면 데이터 레이스 안전이 보호해줄 것입니다 먼저, 가변 상태 유형에 비동기 함수 호출이 더 쉬워졌습니다 특정 액터에 연결되지 않은 비동기 함수를 열심히 오프로드하는 대신 해당 함수는 호출을 받은 액터에서 계속 실행됩니다 비동기 함수에 전달된 값이 액터 밖으로 전송되지 않기 때문에 데이터 레이스가 발생하지 않습니다 비동기 함수는 구현 중인 작업을 오프로드할 수 있지만 클라이언트는 가변 상태에 대하여 걱정할 필요가 없습니다

    또한 주요 액터 유형의 적합성 구현을 더 쉽게 만들었습니다 여기에 Exportable이라는 프로토콜이 있습니다 MainActor StickerModel 클래스 적합성을 구현하고자 합니다 내보내기에는 액터 격리가 요구되지 않기 때문에 언어는 MainActor로부터 호출될 수 있는 것으로 가정했고 StickerModel이 구현 중인 MainActor 상태를 사용하지 못 하도록 했죠

    Swift 6.2는 이러한 적합성을 지원합니다 MainActor 상태가 필요한 적합성을 *격리된* 적합성이라고 합니다 컴파일러는 MainActor 적합성이 MainActor터에만 사용되도록 해 안전합니다 MainActor에 보존되는 한 모든 Exportable 항목 배열에 StickerModel을 추가하는 ImageExporter 유형을 생성하죠 하지만 ImageExporter가 모든 곳에서 사용되도록 허용하면 컴파일러가 배열에 StickerModel을 추가하는 것을 막습니다 MainActor 밖에서 StickerModel에 내보내기를 호출하는 것이 안전하지 않기 때문입니다 격리된 적합성을 사용하면 코드가 동시적으로 적합성을 사용한다고 나타날 때 데이터 레이스 안전 문제만 해결하면 됩니다

    전역 및 정적 변수는 가변 상태에 어디서든 접근할 수 있기 때문에 데이터 레이스에 취약합니다

    일반적으로 전역 상태를 보호하기 위해 MainActor를 사용합니다 그리고 모든 가변 상태를 보호하기 위해 MainActor와 함께 전체 클래스에 주석을 다는 것이 일반적입니다 특히 동시 작업이 많지 않은 프로젝트에서 말이죠 완전히 단일 스레드 형식인 프로그램을 모델링하려면 프로젝트에 있는 모든 것에 @MainActor라고 쓰면 됩니다 단일 스레드 코드를 더 쉽게 모델링할 수 있도록 기본적으로 MainActor를 추론하는 모드를 도입했습니다 MainActor는 기본적으로 모든 가변 상태를 보호하기 때문에 안전하지 않은 전역 및 정적 변수 SDK와 같은 다른 MainActor 기능의 호출 등에 대한 데이터 레이스 안전 오류를 없앱니다 또한 대부분 단일 스레드인 코드에서 동시성 주석을 줄입니다 이 모드는 MainActor에서 대부분의 작업을 수행하는 프로젝트에 적합하며 동시 코드는 특정 유형 또는 파일 내에 캡슐화됩니다 옵트인이며 앱, 스크립트 및 기타 실행 대상에 권장됩니다 작업을 백그라운드로 오프로드하는 것은 CPU 집약적인 작업을 수행할 때 앱 등의 반응성에 여전히 중요합니다 PhotoProcessor에서 extractSticker 메서드로 구현해 보죠 먼저 이미 이미지에 대한 스티커를 추출했는지 확인하므로 즉시 캐시된 스티커를 반환할 수 있습니다 스티커가 캐시되지 않은 경우 이미지 데이터에서 피사체를 추출하여 생성합니다 extractSubject 메서드는 MainActor나 다른 액터를 차단하고 싶지 않은 값비싼 이미지 처리를 수행합니다 @Concurrent 속성을 사용하여 이 작업을 오프로드할 수 있습니다 @Concurrent는 함수가 항상 동시 스레드 풀에서 실행되도록 하여 액터의 역할을 비워 동시에 다른 작업을 수행하도록 합니다 이러한 언어 변경은 동시성을 더 쉽게 다루도록 함께 작동합니다 데이터 레이스 위험이 없는 MainActor에서 기본적으로 실행되는 코드를 작성하는 것으로 시작해보세요 비동기 함수를 사용해보세요 어디서든 호출된 곳에서 실행됩니다 코드는 모두 여전히 MainActor에서 실행되므로 데이터 레이스 위험이 없습니다 성능 향상을 위해 동시성을 수용할 준비가 되면 병렬로 실행될 배경에 특정 코드를 쉽게 오프로드할 수 있습니다 실제로 동시성을 사용하는 것에 대해 자세히 알아보고 싶다면 'Swift 동시성으로 앱 수준 높이기'를 확인하세요 기본적인 동시성 개념에 대해 자세히 알아보려면 'Swift 동시성 사용하기'를 시청하세요 일부 언어 변경은 프로젝트에 변경 사항 도입이 요구되기 때문에 선택 사항으로 구성되었습니다 접근 가능한 모든 동시성 언어 변경 사항은 Xcode 빌드 설정의 Swift 컴파일러 - 동시성 섹션에서 활성화할 수 있습니다 SwiftSettings API를 사용하면 Swift 패키지 매니페스트 파일에서 이러한 기능을 활성화할 수도 있습니다 Swift 6.2에는 필요한 코드 변경 사항을 자동으로 적용할 수 있도록 마이그레이션 도구가 포함되어 있습니다 마이그레이션 도구는 swift.org/migration을 보세요 이러한 동시성 개선점은 프로젝트에 데이터 안전을 도입하는 것에 대한 당신의 피드백을 통해 구체화되었습니다 버그 보고부터 이해가 가지 않는 동시성 오류에 대한 질문 포럼 내 더 좋은 개발 방법 검토와 직접 언어 변경 사항 적용에 이르기까지 당신의 참여가 큰 차이를 만듭니다 동시성에 쉽게 접근할 수 있도록 만들어 주셔서 감사합니다 SWIFT 개선에 참여하고 싶다면 포럼에 가입하세요 누구나 언어와 생태계의 진보를 이끌어나갈 수 있습니다 커뮤니티의 쇼케이싱 섹션에서 당신의 프로젝트에 대해서도 들어보고 싶습니다 또한 회의부터 모임 소셜 미디어에 이르기까지 포럼을 이용하며 Swift에서 일어나는 모든 일에 대한 최신 정보를 확인할 수 있습니다 오늘도 함께 해주셔서 감사합니다 포럼에서 뵙겠습니다

    • 9:44 - Subprocess: Call `run` with string

      import Subprocess
      
      let result = try await run(
        .name("pwd")
      )
    • 10:04 - Subprocess: Call `run` with file path

      import Subprocess
      
      let swiftPath = FilePath("/usr/bin/swift")
      let result = try await run(
        .path(swiftPath),
        arguments: ["--version"]
      )
    • 10:05 - Subprocess: Accessing standard output

      import Subprocess
      
      let swiftPath = FilePath("/usr/bin/swift")
      let result = try await run(
        .path(swiftPath),
        arguments: ["--version"]
      )
      
      let swiftVersion = result.standardOutput
    • 10:51 - NotificationCenter: Dynamic types

      import UIKit
      
      @MainActor 
      class KeyboardObserver {
       func registerObserver(screen: UIScreen) {
          let center = NotificationCenter.default
          let token = center.addObserver(
            forName: UIResponder.keyboardWillShowNotification,
            object: screen,
            queue: .main
          ) { notification in
            guard let userInfo = notification.userInfo else { return }
            let startFrame = userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect
            let endFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
      
            guard let startFrame, let endFrame else { return }
      
            self.keyboardWillShow(startFrame: startFrame, endFrame: endFrame)
          }
        }
        
        func keyboardWillShow(startFrame: CGRect, endFrame: CGRect) {}
      }
    • 11:34 - NotificationCenter: Concrete types

      import UIKit
      
      @MainActor
      class KeyboardObserver {
        func registerObserver(screen: UIScreen) {
          let center = NotificationCenter.default
          let token = center.addObserver(
            of: screen,
            for: .keyboardWillShow
          ) { keyboardState in
            let startFrame = keyboardState.startFrame
            let endFrame = keyboardState.endFrame
      
            self.keyboardWillShow(startFrame: startFrame, endFrame: endFrame) 
          }
        }
        
        func keyboardWillShow(startFrame: CGRect, endFrame: CGRect) {}
      }
    • 12:01 - NotificationCenter: Conformances

      extension UIResponder { 
        public struct KeyboardWillShowMessage: NotificationCenter.MainActorMessage
      }
      
      extension HTTPCookieStorage {
        public struct CookiesChangedMessage: NotificationCenter.AsyncMessage
      }
    • 12:48 - Observation: The @Observable macro

      import Observation
      
      enum Item {
        case none
        case banana
        case star
      }
      
      @Observable
      class Player {
        let name: String
        var score: Int = 0
        var item: Item = .none
      
        init(name: String) {
          self.name = name
        }
      }
    • 12:58 - Observation: The Observations type

      import Observation
      
      enum Item {
        case none
        case banana
        case star
      }
      
      @Observable
      class Player {
        let name: String
        var score: Int = 0
        var item: Item = .none
      
        init(name: String) {
          self.name = name
        }
      }
      
      let player = Player(name: "Holly")
      let values = Observations {
        let score = "\(player.score) points"
        let item =
          switch player.item {
          case .none: "no item"
          case .banana: "a banana"
          case .star: "a star"
          }
        return "\(score) and \(item)"
      }
    • 13:56 - Observation: Transactional updates

      import Observation
      
      enum Item {
        case none
        case banana
        case star
      }
      
      @Observable
      class Player {
        let name: String
        var score: Int = 0
        var item: Item = .none
      
        init(name: String) {
          self.name = name
        }
      }
      
      let player = Player(name: "Holly")
      let values = Observations {
        let score = "\(player.score) points"
        let item =
          switch player.item {
          case .none: "no item"
          case .banana: "a banana"
          case .star: "a star"
          }
        return "\(score) and \(item)"
      }
      
      player.score += 2
      player.item = .banana
    • 14:05 - Observation: AsyncSequence

      import Observation
      
      enum Item {
        case none
        case banana
        case star
      }
      
      @Observable
      class Player {
        let name: String
        var score: Int = 0
        var item: Item = .none
      
        init(name: String) {
          self.name = name
        }
      }
      
      let player = Player(name: "Holly")
      let values = Observations {
        let score = "\(player.score) points"
        let item =
          switch player.item {
          case .none: "no item"
          case .banana: "a banana"
          case .star: "a star"
          }
        return "\(score) and \(item)"
      }
      
      player.score += 2
      player.item = .banana
      
      for await value in values { print(value) }
    • 14:17 - Swift Testing

      import Testing
      import Foundation
      import EvolutionMetadataModel
      
      @Test
      func validateProposalID() async throws {
        let (data, _) = try await URLSession.shared.data(from: evolutionJSONMetadataURL)
      
        let jsonDecoder = JSONDecoder()
        let metadata = try jsonDecoder.decode(EvolutionMetadata.self, from: data)
        for proposal in metadata.proposals {
          #expect(proposal.id.starts(with: "SE"))
        }
      }
    • 14:54 - Swift Testing: Attachments

      import Testing
      import Foundation
      import EvolutionMetadataModel
      
      @Test
      func validateProposalID() async throws {
        let (data, _) = try await URLSession.shared.data(from: evolutionJSONMetadataURL) 
        Attachment.record(data, named: "evolution-metadata.json")
      
        let jsonDecoder = JSONDecoder()
        let metadata = try jsonDecoder.decode(EvolutionMetadata.self, from: data)
        for proposal in metadata.proposals {
          #expect(proposal.id.starts(with: "SE"))
        }
      }
    • 15:23 - Exit Tests: Preconditions

      extension Proposal {
        public var number: Int {
          let components = id.split(separator: "-")
          precondition(
            components.count == 2 && components[1].allSatisfy(\.isNumber),
            "Invalid proposal ID format \(id); expected SE-<Number>"
          )
      
          return Int(components[1])!
        }
      }
    • 15:34 - Exit Tests: processExitsWith argument

      import Testing
      import EvolutionMetadataModel
      
      @Test
      func invalidProposalPrefix() async throws {
        await #expect(processExitsWith: .failure) {
          let proposal = Proposal(id: "SE-NNNN")
          _ = proposal.number 
        }
      }
    • 31:06 - Concurrency: Async function error message

      class PhotoProcessor {
        func extractSticker(data: Data, with id: String?) async -> Sticker? {     }
      }
      
      @MainActor
      final class StickerModel {
        let photoProcessor = PhotoProcessor()
      
        func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
          guard let data = try await item.loadTransferable(type: Data.self) else {
            return nil
          }
      
          return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
        }
      }
    • 32:06 - Concurrency: Run async functions on the caller's actor

      // Run async functions on the caller's actor
      
      class PhotoProcessor {
        func extractSticker(data: Data, with id: String?) async -> Sticker? {}
      }
      
      @MainActor
      final class StickerModel {
        let photoProcessor = PhotoProcessor()
      
        func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
          guard let data = try await item.loadTransferable(type: Data.self) else {
            return nil
          }
      
          return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
        }
      }
    • 32:36 - Concurrency: Conformance error

      protocol Exportable {
        func export()
      }
      
      
      extension StickerModel: Exportable { // error: Conformance of 'StickerModel' to protocol 'Exportable' crosses into main actor-isolated code and can cause data races
        func export() {
          photoProcessor.exportAsPNG()
        }
      }
    • 33:04 - Concurrency: Isolated conformances

      // Isolated conformances
      
      protocol Exportable {
        func export()
      }
      
      
      extension StickerModel: @MainActor Exportable {
        func export() {
          photoProcessor.exportAsPNG()
        }
      }
    • 33:20 - Concurrency: Isolated conformance use

      // Isolated conformances
      
      @MainActor
      struct ImageExporter {
        var items: [any Exportable]
      
        mutating func add(_ item: StickerModel) {
          items.append(item)
        }
      
        func exportAll() {
          for item in items {
            item.export()
          }
        }
      }
    • 33:31 - Concurrency: Isolated conformance error

      // Isolated conformances
      
      nonisolated
      struct ImageExporter {
        var items: [any Exportable]
      
        mutating func add(_ item: StickerModel) {
          items.append(item) // error: Main actor-isolated conformance of 'StickerModel' to 'Exportable' cannot be used in nonisolated context
        }
      
        func exportAll() {
          for item in items {
            item.export()
          }
        }
      }
    • 33:51 - Concurrency: Unsafe static variable

      final class StickerLibrary {
        static let shared: StickerLibrary = .init() // error: Static property 'shared' is not concurrency-safe because non-'Sendable' type 'StickerLibrary' may have shared mutable state
      }
    • 34:01 - Concurrency: Protecting static variables

      final class StickerLibrary {
        @MainActor
        static let shared: StickerLibrary = .init()
      }
    • 34:05 - Concurrency: Protecting classes

      @MainActor
      final class StickerLibrary {
        static let shared: StickerLibrary = .init()
      }
    • 34:15 - Concurrency: A single-threaded program

      @MainActor
      final class StickerLibrary {
        static let shared: StickerLibrary = .init()
      }
      
      @MainActor
      final class StickerModel {
        let photoProcessor: PhotoProcessor
      
        var selection: [PhotosPickerItem]
      }
      
      extension StickerModel: @MainActor Exportable {
        func export() {
          photoProcessor.exportAsPNG()
        }
      }
    • 34:22 - Concurrency: Mode to infer main actor by default

      // Mode to infer main actor by default
      
      final class StickerLibrary {
        static let shared: StickerLibrary = .init()
      }
      
      final class StickerModel {
        let photoProcessor: PhotoProcessor
      
        var selection: [PhotosPickerItem]
      }
      
      extension StickerModel: Exportable {
        func export() {
          photoProcessor.exportAsPNG()
        }
      }
    • 35:06 - Concurrency: Explicitly offloading async work

      // Explicitly offloading async work
      
      class PhotoProcessor {
        var cachedStickers: [String: Sticker]
      
        func extractSticker(data: Data, with id: String) async -> Sticker {
            if let sticker = cachedStickers[id] {
              return sticker
            }
      
            let sticker = await Self.extractSubject(from: data)
            cachedStickers[id] = sticker
            return sticker
        }
      
        @concurrent
        static func extractSubject(from data: Data) async -> Sticker {}
      }
    • 0:00 - Introduction & Agenda
    • Learn what's new in Swift 6.2. Highlights include: workflow enhancements, new library APIs, expanded adoption across the software stack, and improved concurrency language features for more productive coding.

    • 0:48 - swiftlang updates
    • The swiftlang organization on GitHub has grown significantly, encompassing over 50 projects, including the Swift compiler, Xcode’s build system Swift Build, and the Swift.org website. Swift Build, now open source, supports the build process for Apple operating systems, and is adopted by the Swift Package Manager. A new version manager, swiftly, originally developed for Linux, now supports macOS and simplifies Swift toolchain management. The redesigned Swift.org homepage can also help you dive into different areas.

    • 3:06 - Development workflow: Writing code
    • The latest Swift release enhances development workflows across all platforms, with specific improvements for VS Code Swift extension users including official verification and distribution of the Swift extension by Swift.org. Now, there's also background indexing for real-time editor features, enhanced code completion, simplified debugging with automatic LLDB support, and new project panel and live DocC previews.

    • 4:40 - Development workflow: Building
    • Swift 6.2 introduces several enhancements to boost your productivity. Clean build times for projects utilizing macro-based APIs are significantly improved by eliminating the need to build the swift-syntax library during clean builds. This optimization, supported by Swift PM and Xcode, can reduce build times by minutes. This release also enhances compiler diagnostics documentation by providing more detailed explanations of common warnings and errors, making them easier to understand and resolve. Additionally, you now have greater control over compiler warnings; you can specify which warnings to treat as errors, a feature driven by community feedback.

    • 7:36 - Development workflow: Debugging
    • Debugging is also enhanced in Swift 6.2, particularly for asynchronous code, with improved LLDB functionality, task naming and visibility in Instruments profiles. It also has faster debugger response times due to explicitly built modules enabled by default in Xcode 26.

    • 9:14 - Libraries: Subprocess
    • This release introduces the new Subprocess package, with which you can launch and manage subprocesses directly from Swift code. The package gives you fine-grained control over process execution, so you can specify the executable path. When the subprocess terminates, you can inspect the exit status, standard output, and other information about the process execution, with version 0.1 now available and ready for feedback.

    • 10:45 - Libraries: Foundation
    • The Foundation Workgroup enhanced iOS app development by introducing concrete types for notification names and payloads, streamlining code, eliminating errors, and improving thread safety for both framework and custom notifications. You can also add concrete notification types for your own notifications.

    • 12:31 - Libraries: Observation
    • The Observation Library in Swift uses the observer pattern to track state changes in an object graph. The 'Observable' macro enables observation tracking. Swift 6.2 introduces the 'Observations' type, with which you can create an 'AsyncSequence' to stream state changes based on a closure that computes a value from observable properties. Updates are transactional, ensuring consistent state, and you can iterate over them using a for-await loop.

    • 14:13 - Libraries: Testing
    • Using Swift Testing, a cross-platform library, you can write and organize tests by using macros. Swift 6.2 enhances this capability with custom attachments for better failure diagnosis, especially in remote environments, and exit tests to validate code that terminates under specific conditions. These features support testing portable Swift code, beyond just your application code.

    • 16:08 - Swift throughout the stack: Embedded Swift
    • Swift 6.2 enhances Embedded Swift, enabling you to write code for embedded devices, servers, and security-critical components. It now includes full-string APIs, Swift's 'any' types for class-constrained protocols, and new APIs like 'InlineArray' and 'Span' for working efficiently with regions of memory. Apple uses Embedded Swift in some of the lowest-level software on iPhone, and the community created examples available on GitHub in the swift-embedded-examples repository.

    • 18:00 - Swift throughout the stack: Security
    • Swift 6.2 introduces strict-memory-safety mode, an opt-in feature that requires explicit acknowledgment of unsafe API uses, aiding in identifying security-critical code sections. Apple is adopting this mode in WebKit and a Messages app subsystem, which both handle untrusted input.

    • 19:37 - Swift throughout the stack: Server
    • Swift is widely used in the server ecosystem, particularly at Apple, where it powers backend services processing millions of requests per second. A notable example is a password alert service, previously built in Java, which saw a 40% increase in throughput and a 50% reduction in hardware requirements after being rewritten in Swift. Other companies, such as Cultured Code, also benefited significantly from adopting Swift. The Things Cloud backend, reimplemented in Swift, experienced a 3x reduction in compute costs and a 400% improvement in average response times. Swift's growing package ecosystem, interoperability with C, Objective-C, and C++, and new open source projects like swift-java and a containerization library, enable developers to build efficient, performant server backends, and seamlessly integrate Swift with existing codebases, particularly in Java.

    • 23:23 - Swift throughout the stack: Platforms
    • Swift 6.2 now officially supports FreeBSD and WebAssembly (Wasm), enabling you to build client and server applications for browsers and other runtimes. The Wasm support, which started as a community project, allows you to compile Swift code and run it in the browser, as demonstrated by a 3D rendering app using WebGPU and JavaScriptKit. Swift's safety, ease of use, and performance make it an attractive choice throughout the software stack.

    • 26:11 - Language evolution: Performance
    • The new release also introduces two new types, 'InlineArray' and 'Span', to enhance performance of critical code. 'InlineArray' is a fixed-size array that stores elements directly, eliminating the need for heap allocation. This improves performance, especially in hot paths, and enables more optimizations like eliminating bounds checking. The system specifies the size of an 'InlineArray' as part of the type, and can infer it from array literals. 'Span' provides fast, direct access to contiguous memory without compromising memory safety. It allows functions to operate over the underlying storage of various container types, such as 'Array' and 'InlineArray', safely and efficiently. 'Span' ensures memory validity through compile-time checks, preventing common memory safety issues inherent to pointers.

    • 30:28 - Language evolution: Concurrency
    • Concurrency is a challenging aspect of programming due to the potential for data races when multiple tasks share memory. Swift 6 introduced data-race safety at compile time, but this often led to compiler errors when because the language would offload work to the background implicitly, even if you never needed the code to run in parallel. Swift 6.2 addresses this issue by changing the default philosophy to stay single-threaded until the you explicitly introduce concurrency. This capability, by default, makes the most natural code to write data race-free. The language now allows async functions that aren't tied to a particular actor to continue in the same actor it was called from, eliminating data races. The release also introduces isolated conformances, enabling main actor types to conform to protocols while ensuring the compiler protects main actor state. Additionally, there's now an opt-in mode to infer the main actor by default, reducing concurrency annotations in mostly single-threaded code. When you need concurrency for performance improvement, such as offloading CPU-intensive tasks to the background, Swift 6.2 provides tools to do so safely. The concurrent attribute ensures that specific functions run on the concurrent thread pool, freeing up the current actor to perform tasks simultaneously. These changes work together to make concurrency more approachable and easier to implement in Swift projects.

    • 37:15 - Wrap up
    • User feedback led to Swift's concurrency improvements, making it more user friendly. The community is encouraged to participate in the forums at Swift.org to continue language and ecosystem development, share projects, and stay updated on Swift-related events.

Developer Footer

  • 비디오
  • WWDC25
  • Swift의 새로운 기능
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드(영문)
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    Apple Developer 앱 받기
    Copyright © 2025 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침