View in English

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

빠른 링크

5 빠른 링크

비디오

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

WWDC25 컬렉션으로 돌아가기

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

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

    WidgetKit은 위젯, 실시간 현황 및 제어 기능 업데이트로 앱의 수준을 높입니다. 위젯을 visionOS로 가져오고, 운전하는 동안 CarPlay로 사용하며, 강조 표시 렌더링 모드로 가장 돋보이게 하는 방법을 알아보세요. 또한 watchOS의 스마트 스택에서 관련 위젯이 표시되는 방법과 푸시 알림을 사용하여 위젯을 최신 상태로 유지하는 방법을 확인하세요.

    챕터

    • 0:00 - Introduction
    • 1:03 - Widgets in new places
    • 15:31 - Relevance widgets
    • 18:12 - Push widget updates

    리소스

    • Increasing the visibility of widgets in Smart Stacks
    • Optimizing your widget for accented rendering mode and Liquid Glass
    • RelevanceKit
    • Updating widgets with WidgetKit push notifications
    • Updating your widgets for visionOS
      • HD 비디오
      • SD 비디오

    관련 비디오

    WWDC25

    • CarPlay용 앱 성능 강화하기
    • visionOS용 위젯 디자인하기
    • watchOS 26의 새로운 기능

    WWDC24

    • 시스템 전반에서 앱의 제어 기능 확장하기
    • Apple Watch용 실시간 현황 디자인하기

    WWDC23

    • 새 위치로 위젯 가져오기
    • 푸시 알림 콘솔 알아보기

    WWDC20

    • 푸시 알림 입문서
  • 비디오 검색…

    안녕하세요 저는 Tanner Oakes입니다 System Experience 팀 엔지니어죠 위젯은 시스템에서 시기적절한 정보와 동작을 표시하기 좋습니다 앱을 전면이나 중앙에 두지 않고도 유용하게 사용할 수 있죠 WidgetKit이 계속 확장되어 위젯이 더 강력해졌습니다 새로운 경험을 만나보세요 제 친구 Luca는 카페인 섭취 기록 앱을 작업하는데 제가 그 업데이트 작업을 돕고 있어요 이 세션에서는 새 위젯 기능을 활용하는 방법을 모두 보여드릴게요 이 영상에서는 플랫폼의 새로운 곳에서 위젯, 실시간 현황과 제어 기능을 활용하는 법을 살펴보겠습니다 Apple Watch의 스마트 스택에서 관련 위젯 콘텐츠를 표시하는 새로운 방법도 살펴볼게요 마지막으로 푸시 알림을 통해 기기 간에 위젯을 최신 상태로 유지하는 방법을 보여 드릴게요 위젯, 실시간 현황 및 제어를 여러 새로운 곳에서 사용합니다 먼저, 기존 위치에서 보는 위젯의 새로운 모습은 어떤지 살펴보겠습니다 iOS 26에서는 투명 유리 프리젠테이션에서 아이콘과 위젯을 표시하기 위해 홈 화면을 구성할 수 있습니다 또는 파란색처럼 원하는 색조로 추가적인 사용자화가 가능하죠 외관은 데스크탑이나 macOS Tahoe 상 알림 센터의 위젯에 맞게 구성할 수도 있습니다 새로운 프레젠테이션은 iOS와 macOS에서 비슷하게 구성됩니다 먼저, 위젯 콘텐츠는 강조 렌더링 모드로 생성되어 모든 내용을 흰색으로 채색합니다 그런 다음 위젯 백그라운드가 제거되고 테마 유리 또는 색조 색상 효과로 대체되었습니다 아무것도 할 필요 없이 악센트 모드에 두니 카페인 추적 위젯이 멋져 보이네요 어떤 위젯은 악센트 모드에서 약간의 조정이 필요하기도 합니다 이 앱에 가장 자주 마시는 음료를 보여주는 위젯을 추가했습니다 제 음료는 말차 라떼죠 위젯에는 음료를 나타내는 큰 이미지와 하단의 제목 텍스트 뒤의 그라디언트가 있어 이미지 위에 두면 가독성을 높여줍니다 악센트 렌더링을 적용하면 위젯의 모든 콘텐츠가 흰색으로 표시됩니다 라떼 컵처럼 불투명한 객체는 모두 같은 흰색으로 표시됩니다 그라디언트와 같이 일부 투명한 내용물은 불투명도를 유지하며 흰색으로 색조가 입혀집니다 제가 원하는 것과는 조금 다르네요 원하는 이미지가 아니고 텍스트는 읽기가 어렵습니다 더 나은 강조 렌더링을 위해 위젯을 업데이트 해보겠습니다 여기 위젯이 보이죠 음료 이미지와 ZStack이 있고 그라디언트 및 텍스트 보기가 있죠 widgetRenderingMode 환경 변수를 위젯 보기에 추가합니다 위젯이 풀 컬러로 렌더링되는 경우에만 큰 이미지와 선형 그라디언트를 조건부로 표시하겠습니다 Vstack을 추가하고 위젯이 악센트 모드일 때 이미지를 조건부로 표시하도록 설정한 후 이미지를 텍스트로 가져옵니다 레이아웃이 꽤 좋아 보이네요 이제 이미지의 모습을 개선해야 합니다 실시간 현황의 이미지에 widgetAccentedRenderingMode 수정자를 저채도 상태로 설정합니다 widgetAccentedRenderingMode는 위젯의 이미지에 적용할 수 있는 SwiftUI 수정자입니다 전달할 인수가 악센트 모드에서 이미지가 어떻게 보일지 세밀히 제어할 수 있죠 widgetAccentedRenderingMode가 수용하는 선택지는 다섯 개입니다 각 모드가 이미지 표현에 어떤 영향을 미치는지 보여 드릴게요 iOS 및 macOS와 시계 페이스를 악센트 모드에서 비교해서요

    widgetAccentedRenderingMode의 경우에 nil 전달은 수식어를 전혀 적용하지 않는 것과 같습니다 기본 콘텐츠 색상을 이미지에 적용하죠 iOS와 watchOS 위젯에선 이미지를 완전히 흰색으로 만듭니다 강조를 전달하면 이미지가 강조 색상으로 변합니다 iOS 및 macOS에서는 기본 색상과 강조 색상이 모두 흰색이 되어 이미지도 흰색으로 변합니다 watchOS에서 강조 색상은 시계 페이스의 색상과 일치하니 watchOS 위젯의 이미지가 파란색이 됩니다 채도 감소를 거치면 이미지 색상 채도도 낮아집니다 iOS, watchOS 프레젠테이션 스타일 모두에서 동일하게 보입니다 accentedDesaturated을 전달하면 두 효과가 모두 적용되어 이미지 색상 채도를 낮추고 선택한 테마의 강조 색상을 적용합니다 iOS에서 이는 이미지를 조금 더 하얗게 보이게 합니다 WatchOS에서는 저채도 이미지에 테마에서처럼 파란색 강조 색상이 입혀집니다 fullColor를 전달하면 강조 렌더링 모드에서도 이미지가 전혀 수정되지 않습니다 시계 페이스와 잘 어우러지도록 watchOS에선 이 옵션이 무시됩니다 대부분의 위젯의 경우, 저채도 또는 강조 채도 감소를 사용해 이미지 콘텐츠가 홈 화면과 조화를 이룰 수 있도록 합니다 앨범 아트워크나 책 표지 같이 미디어 콘텐츠를 나타내는 이미지에는 풀 컬러를 사용합니다 다음으로는 완전히 새로운 차원의 위젯 사용법을 보여드리겠습니다 이제 VisionOS 26에서는 VisionOS 앱에서 위젯 사용이 가능합니다 위젯 사용이 가능하고 호환되는 iPhone 및 iPad 앱이 이미 있다면 자동으로 해당 앱을 VisionOS에서 사용할 수 있게 됩니다 iOS 및 macOS의 모든 시스템 제품군 크기가 지원됩니다 다른 플랫폼과 같이 VisionOS에서 위젯은 상호작용 및 애니메이션 기능을 갖추었습니다 Vision OS 위젯 작동방식과 새로운 WidgetKit 옵션을 보여 드리죠 Vision OS에서는 위젯을 방에 추가해 표면에 고정할 수 있습니다 기본적으로 표면 위에 얹혀 약간 떠 있는 모습일 것입니다 위젯을 오목하게 만들 수도 있어 표면에 곧바로 임베드된 것처럼 보이게 할 수 있습니다 위젯에 이런 스타일이 잘 맞지 않는 경우 supportedMountingStyles 수정자로 위젯 구성에서 적용할 옵션을 명시하세요 이 수정자는 VisionOS 및 iOS 위젯 모두에서 사용할 수 있습니다 기본적으로 모든 위젯은 유리 텍스처 아래에 렌더링됩니다 visionOS의 경우 다른 종이 질감을 명시하여 위젯에 포스터와 같은 스타일을 입힐 수 있습니다 여기 왼쪽에는 유리로 구성된 자주 마시는 음료 위젯이 있고 오른쪽에는 같은 위젯에 종이 질감을 입혀 테스트를 진행하고 있습니다 위젯 구성에서 widgetTexture 식별자를 사용해 위젯에 종이 질감을 입힐지 유리 뒤에 둔 효과를 주어 렌더링할지 명시합니다 위젯 외관을 포스터처럼 만들게 도와주는 새 위젯 제품군 systemExtraLargePortrait를 visionOS에서 만나보세요 이는 기존 가로 systemExtraLarge 위젯 제품군의 세로 버전입니다

    supportedFamilies 수정자를 사용하여 위젯 구성에 추가합니다 Vision OS에서는 위젯의 색상 테마도 사용자화 가능합니다 기본적으로 위젯은 풀 컬러 프레젠테이션으로 표시됩니다 초록색 테마를 선택하면 위젯의 콘텐츠가 강조된 렌더링이 적용돼 이미지가 전혀 수정되지 않습니다 위젯 프레임과 콘텐츠는 선택한 색상으로 색이 입혀집니다 그후 백그라운드가 제거되고 선택한 컬러 테마를 보완하는 단일 색상으로 대체됩니다 이 스타일은 앞서 iOS 및 macOS에 대해 논의한 것과 동일한 렌더링 접근법을 적용합니다 이번에 살펴본 것과 같은 테크닉을 사용해 이런 색상 테마에서 위젯이 멋져보이도록 설정해보세요 widgetAccentedRenderingMode 수정자를 사용하여 이미지를 어떻게 내보일지 맞춤화하세요 widgetRenderingMode 환경 변수를 사용해 더 실질적인 수정을 조건부로 적용하세요

    Vision Os에서는 위젯을 환경으로 가져와 여러 표면에 놓을 수 있습니다 다른 공간으로 이동해도 위젯은 고정된 위치에 유지됩니다 위젯이 멀리 방 건너편 벽에 떨어져 있어도 실물과 같이 더 멀리 있는 위젯은 더 작고 보기 어렵게 표시되지만 VisionOS 위젯은 실물과 다르게 LevelOfDetail API를 사용해 거리를 기반으로 적응합니다 카페인 추적 위젯에 LevelOfDetail을 추가하는 방법을 보여드리겠습니다

    하루 동안 섭취한 총 카페인과 마지막으로 마신 음료 및 다른 음료를 추가할 수 있는 편리한 버튼을 보여주는 기존 위젯이 있습니다 이 위젯이 더 멀리 떨어져 있을 때 총 카페인 값을 더 크게 표시해 읽기 쉽게 만들고 싶어요 또한 버튼을 숨기고 싶습니다 멀리 있으면 누르기 힘들테니까요 카페인 추적 위젯이 여기 있네요 TotalCaffeineView를 업데이트해 크기를 변경하고 하단의 LogDrinkView를 조건부로 표시하거나 숨기고 싶어요 먼저 환경 속성인 LevelOfDetail를 보기에 추가하겠습니다 LevelOfDetail은 두 값 중 하나여야 합니다 기본값은 위젯에 일반적으로 기대하는 수준의 세부 정보입니다 VisionOS에서 위젯이 편한 거리에 있을 때에는 세부정보가 기본값 수준으로 표시됩니다 위젯이 물리적으로 먼 거리에 있을 때에는 세부정보가 간소화되어 보다 단순하고 간단한 정보를 표시해 위젯을 더 쉽게 훑어볼 수 있게 해줍니다 이 조건을 LogDrinkView에 추가해 LevelOfDetail이 기본값일 때만 표시하도록 설정하겠습니다 이제 카페인 양을 업데이트해야 합니다

    총 카페인 보기에 제목과 포매팅된 총 카페인 양이 표시되어 있습니다 먼저, 보기에 LevelOfDetail 환경 변수를 추가합니다 더 크게 표시하려면 정보의 수준에 기반하여 제목의 카페인 양 폰트를 조건부로 크게 만들어야 합니다

    이제 위젯이 충분히 멀리 떨어져 있을 때마다 위젯이 더 간결해져 쉽게 훑어볼 수 있도록 변합니다 또한, 위젯 내의 타임라인 변경과 마찬가지로 세부정보의 변화 수준에도 애니메이션 효과가 적용됩니다 제안된 세부정보 수준이나 공간 스타일을 사용자화 하는 경우 새 플랫폼에 위젯을 불러올 때의 고려사항 대해 자세히 알아보려면 'visionOS용 위젯 디자인하기'를 살펴보세요 기어를 바꾸어 이제 CarPlay에서 위젯과 실시간 현황을 사용하는 법을 알아봅시다 CarPlay Ultra에서 위젯은 대시보드 왼쪽에 있는 하나 이상의 스택에 나타납니다 그리고 iOS 26부터는 이 기능을 CarPlay를 탑재한 모든 차량에서 활용할 수 있죠 위젯은 CarPlay 아래의 설정 앱에서 구성할 수 있습니다 차량 디스플레이에서 위젯을 쉽게 읽어야 하니 CarPlay에서는 한눈에 들어오는 정보, 큰 폰트와 가독성이 모두 중요합니다 이를 위해 CarPlay는 위젯을 StandBy 스타일로 렌더링합니다 systemSmall군을 fullColor로 사용해 위젯 백그라운드를 제거합니다 위젯 상호작용은 터치스크린을 통해 지원됩니다 개발자 사이트에서 CarPlay 시뮬레이터를 사용해 테스트를 해볼 수 있죠 StandBy 프레젠테이션에 위젯을 적응시키는 팁을 보려면 WWDC 23의 '새 위치로 위젯 가져오기'를 시청하세요 실시간 현황은 CarPlay의 홈 화면에도 표시될 수 있습니다 기본적으로 실시간 현황의 Dynamic Island 선행 및 후행 뷰가 표시됩니다 CarPlay에 커피 주문 추적 실시간 현황이 표시되어 있네요 시작하기에는 무난하지만 코딩을 조금 더 하면 더 좋게 만들 수 있죠 제 실시간 현황 코드입니다 현재, 내 선행 뷰 및 후행 뷰가 표시되어 있죠 CarPlay용 실시간 현황 프레젠테이션을 사용자화하려면 supplementalActivityFamilies 수정자를 추가하고 내 활동 구성에 대한 인수로 작게 먼저 전달해봅니다 이제 선행 뷰 및 후행 뷰를 사용하는 대신 CarPlay가 내 활동 뷰를 표시합니다 iPhone 잠금 화면에서 사용되는 것과 동일한 보기입니다 일부 실시간 현황의 경우 이대로도 멋져 보일 수 있지만 이번 경우 일부 내용이 끊겨 조금 비좁아 보입니다 다행히도, 더 사용자화할 수 있죠

    제 활동 뷰입니다 보기에 activityFamily 환경 변수를 추가하겠습니다 추가하면, 보기 본문에 조건부로 다른 내용을 표시하도록 하거나 훌륭한 경험을 제공하기 위해 레이아웃을 조정할 수 있습니다 activityFamily가 작은 경우 더 작은 레이아웃에 최적화된 주문 보기를 제공하고 그렇지 않으면 기본 주문 보기를 표시합니다 조금만 더 코딩을 하면 CarPlay에서도 실시간 현황을 멋지게 표시할 수 있습니다 이제 음료 언제 준비될지 빠르게 알 수 있습니다 supplementalActivityFamily를 채택하니 Apple Watch와 페어링해 표시될 때에도 실시간 현황이 훨씬 더 좋아 보입니다 iPhone 앱에도 자동으로 표시됩니다 별도의 watchOS 앱이 필요하지 않습니다 watchOS 스마트 스택에서 실시간 현황을 가장 잘 나타내는 방법에 대해 자세히 알아보려면 'Apple Watch용 실시간 현황 디자인하기'와 'CarPlay용 앱 성능 강화하기'를 살펴보고 위젯을 제대로 가속화하는 방법을 알아보세요 실시간 현황은 CarPlay에서만 새롭게 사용하는 것이 아닙니다 페어링한 iPhone의 실시간 현황이 이제 macOS Tahoe에 표시됩니다 iPhone의 Dynamic Island처럼 커피 주문 추적기 실시간 현황도 메뉴 막대에서 선행 뷰와 후행 뷰를 함께 표시합니다 실시간 현황을 선택하면 iPhone 잠금 화면이 나타납니다 잠금 화면 프레젠테이션을 클릭하면 iPhone 미러링으로 관련 앱이 실행됩니다 macOS의 실시간 활동은 iOS 18 및 이후 버전 iPhone에서 사용합니다 코드 변경 없이도 macOS의 iPhone 위젯과 마찬가지로 상호작용과 딥링크를 지원합니다 이제 macOS 및 watchOS에서 제어 가능한 새로운 지점을 보죠 macOS에서는 Mac에서 실행하는 앱을 통해 제어 기능을 제공합니다 macOS SDK이든 Catalyst 또는 Apple Silicon Mac에서 실행되는 iOS 앱이든 말이죠 제어 센터에서 제어 기능을 추가할 수 있습니다 iOS에서 사용하는 것과 동일한 소, 중, 대형 프레젠테이션도 macOS에서 구성할 수 있습니다 제어 기능을 메뉴 막대에 직접 배치할 수도 있습니다 macOS의 앱에 커피 추적기 제어기를 추가했습니다 메뉴바에서 커피 기록을 쉽게 업데이트할 수 있습니다 watchOS 26에서는 제어 기능이 세 곳에 나타날 수 있습니다 제어 센터에서 제어 기능을 구성할 수 있으며 이는 측면 버튼을 통해 접근할 수 있습니다 Apple Watch Ultra의 동작 버튼을 누를 때도 제어 기능을 실행할 수 있습니다 이는 스마트 스택에서 구성 가능하며 제어 기능의 기호, 제목 및 현재 값을 표시하는 다른 위젯과 함께 나타납니다 제어 기능은 페어링한 디바이스의 watchOS 앱 또는 iPhone 앱에서 제공할 수 있습니다 제어 기능 구축에 대한 광범위한 가이드를 보려면 WWDC24의 '시스템 전반으로 앱의 제어 기능 확장하기'를 확인하세요 이제 watchOS 26의 스마트 스택의 관련 위젯을 보죠 watchOS의 카페인 추적 앱에 위젯을 추가했습니다 단골 카페의 반값 해피아워를 추적하도록 도와주는 위젯이죠 이 위젯으로 개선하고 싶은 것은 두 가지입니다 먼저, 여러 커피숍의 해피아워를 추적하고 있기 때문에 시간이 겹칠 때가 잦아 스마트 스택에 표시되는 위젯 내용이 빽빽하게 나타납니다 또한 해피아워는 시간대가 비슷한 경향이 있습니다 따라서 해피아워가 아닌 시간대에는 위젯이 필요 없죠 해피아워 위젯은 관련성이 높을 때만 스마트 스택에 표시되어 각 활성화된 해피아워에 대한 더 자세한 정보를 보여주길 바랍니다 watchOS 26의 관련성 위젯을 사용하면 가능한 일입니다 해피아워를 관련성 높은 위젯으로 구성해보겠습니다 관련 위젯을 정의하려면 위젯 유형을 생성하고 StaticConfiguration 또는 AppIntentConfiguration 대신 RelevanceConfiguration을 제공합니다 다른 구성과 마찬가지로 일종의 문자열, 공급자 객체 사용자화 항목을 SwiftUI 보기로 변환할 클로저가 필요합니다 제공자 유형은 RelevanceEntriesProvider입니다 자리 표시자 및 관련성 메서드는 TimelineEntriesProvider와 유사하죠 자리 표시자의 경우 콘텐츠가 준비되는 동안 표시할 간단한 항목을 반환할 수 있습니다 관련성을 위해 먼저 정의한 구성 객체를 가져옵니다

    해피아워 위젯에 대해 관련성은 시작과 종료 시간과 연관하여 구성해야 합니다 이 맥락에서 관련성 속성을 각 해피아워의 날짜 간격을 사용하여 설정합니다 그런 다음 입력 메서드를 구현합니다 타임라인 위젯과는 달리 RelevanceEntriesProvider는 구성에 대한 단일 항목만 제공합니다 구성에 이 항목에 필요한 모든 데이터와 상점 데이터 해피아워의 시간 범위를 이미 갖고 있으니 즉시 만들어보겠습니다 다른 데이터나 애셋이 필요한 경우 여기서 가져올 수 있습니다 비동기로 표시된 방법이니까요 이제 관련 위젯을 설정하면 해피아워 위젯이 관련있을 때만 스마트 스택에 표시됩니다 또한 관련된 여러 구성이 동시에 존재하는 경우 스마트 스택에서 내 위젯의 여러 인스턴스를 볼 수 있습니다 관련성 위젯은 watchOS 26의 강력한 새 기능입니다 위젯 콘텐츠를 관련성과 직접 연결하는 기능을 제공합니다 이 위젯들은 기존 타임라인 기반 위젯과 더불어 그 자체로 훌륭한 추가 기능입니다 관련성 위젯에 대해서는 Anne이 진행하는 'watchOS 26의 새로운 기능'을 시청하세요 이제 위젯을 표시할 수 있는 장소와 플랫폼이 많네요 위젯이 어디에 있든 항상 최신 상태로 유지하고자 합니다 최근에 카페인 기록 데이터를 모든 디바이스에서 동기화하도록 서버를 추가했습니다 위젯을 새로 고치는 데 사용할 옵션이 무엇인지 설명하겠습니다 예약된 위젯 리로딩부터 시작하죠 이 다이어그램의 왼쪽에는 앱 번들이 있습니다 앱과 위젯 확장 프로그램이 포함되어 있죠 오른쪽에는 위젯 키트를 나타내는 상자가 있습니다 iPhone 홈 화면이나 시계 페이스 등 디바이스에 위젯이 구성되면 WidgetKit은 위젯 확장 프로그램에 타임라인을 요청합니다 확장 프로그램은 TimelineReloadPolicy이 포함된 위젯 타임라인에 응답합니다 WidgetKit은 해당 위젯을 다시 로드할 적절한 시간을 결정합니다 TimelineReloadPolicy는 일정한 간격으로 업데이트가 필요한 위젯에 사용하기 좋습니다 카페 운영 시간이나 날씨 위젯 또는 주식 위젯과 같은 경우 유용하죠 예정된 타임라인 리로딩 시 성능과 배터리 수명 유지를 위해 시스템이 예산을 짭니다

    WidgetCenter API는 앱에서 사용하는 또 다른 옵션입니다 앱 내에서 위젯에 반영될 데이터 변경이 발생하면 WidgetCenter의 reloadAllTimelines 또는 reloadTimelines(ofKind:) 메서드를 호출할 수 있습니다 위젯의 콘텐츠가 오래되어 다시 로드해야 한다는 것을 WidgetKit에 알려주죠 WidgetKit은 위젯 확장 프로그램에 타임라인을 요청해 위젯을 업데이트합니다 주로 앱 내에서 콘텐츠가 변경되는 경우 훌륭한 옵션입니다 카페인 기록 업데이트 메모 변경 또는 미리 알림 체크와 같이 말이죠 API가 호출될 때 앱이 실행 중이므로 시스템은 요청의 예산을 책정하지 않습니다 그런데 서버나 다른 기기에서 데이터가 변경되면 어떨까요? 위젯 푸시 업데이트는 이럴 때 유용합니다 데이터 변경사항 추적 서버는 APNS에 푸시 알림을 보내 WidgetKit에게 해당 앱의 위젯을 다시 로드하라고 전달합니다 다른 업데이트와 유사하게 WidgetKit은 위젯에서 업데이트된 타임라인을 요청합니다 위젯 푸시 업데이트는 데이터가 장치 외부에서 변경될 수 있는 환경에서 특히 유용합니다 TimelineReloadPolicy와 동일하게 위젯 푸시 알림 업데이트도 성능과 배터리 수명 유지를 위해 예산이 책정됩니다 위젯으로 다양한 상황에 맞게 리로드를 할 수 있는 선택지가 많아졌습니다 상호배타적이지 않은 선택지입니다 두 개 또는 세 개의 선택지를 위젯에서 사용하고 싶을 수 있죠 위젯 푸시 업데이트를 사용하면 iPad 앱, Vision Pro 위젯 macOS 메뉴 막대 제어 기능 등 어디서 업데이트하든 위젯의 카페인 기록을 최신 상태로 유지합니다 위젯에 추가하는 방법을 보여드리겠습니다 WidgetPushHandler를 만들어 위젯 구성에 추가하고 위젯 확장 프로그램에 푸시 알림 권한을 추가한 후 위젯 업데이트 푸시 요청을 구성합니다 WidgetPushHandler 프로토콜을 준수하는 구조부터 만들어보죠 푸시 토큰이 변경되거나 구성된 위젯 세트가 변경될 때 저희가 알림을 내보내는 방법이기도 합니다 pushTokenDidChange 메서드로 서버에 푸시 토큰과 위젯 정보를 보내보세요 이제 위젯 구성을 업데이트해야 합니다 여기서 카페인 추적기 위젯에 대한 구성을 볼 수 있습니다 위젯의 이미지에 pushHandler 수정자를 추가해 푸시 알림에 대한 지원을 등록해보겠습니다 이 수정자의 경우엔 구현한 위젯 pushHandler 유형을 전달하죠

    마지막으로, Xcode에서 위젯 확장 프로그램의 Signing & Capabilities 탭으로 이동합니다 푸시 알림 권한을 추가하여 APN과 소통하도록 설정하겠습니다 위젯에 푸시 업데이트를 위한 구성을 마쳤으므로 위젯 업데이트 푸시 알림을 보내는 방법을 보여드리겠습니다 푸시 알림을 통해 위젯을 업데이트하려면 HTTPS POST 요청을 Apple 푸시 서버에 전달합니다 WidgetPushHandler에 제공된 위젯 푸시 토큰을 요청 경로의 마지막 부분으로 사용합니다 헤더에는 위젯 APN 푸시 유형을 사용하고 .push-type.widgets.로 시작하는 앱의 번들 ID를 사용해 APNS 주제 헤더를 구성합니다 앱 사전의 요청 본문에는 콘텐츠 값의 변경된 키를 참으로 설정합니다 푸시 알림에 대해 알아보려면 '푸시 알림 입문서'를 시청하고 '푸시 알림 콘솔 알아보기'에서 손쉽게 푸시 알림 요청을 테스트하는 방법을 알아보세요 위젯 푸시 업데이트는 위젯 콘텐츠를 최신 상태로 유지하지만 상황이 맞을 때 실행되기 때문에 다른 알림 환경을 직접 대체하지 않습니다 긴급하거나 중요한 업데이트가 있는 경우 사용자 알림을 제공하세요 음료 주문과 스포츠 점수 업데이트 또는 항공편 업데이트 등 한정된 시간 동안 정기적인 업데이트가 필요하다면 실시간 현황을 사용하세요 위젯 푸시 업데이트로 위젯 콘텐츠를 최신 상태로 유지합니다 위젯 푸시 업데이트는 모든 위젯 지원 플랫폼에서 사용됩니다 위젯 푸시 알림을 보내면 장치에 구성된 모든 푸시 활성화 위젯을 업데이트합니다 위젯 리로딩에는 예산이 책정됨을 잊지 말아야 합니다 업데이트 푸시를 제한해보세요 서버 상 업데이트에 스로틀링을 적용해볼 수 있습니다 개발 및 테스트 단계에서 설정의 WidgetKit 개발 모드를 사용해 푸시를 무시하고 앱에 대한 예산을 다시 로드하도록 설정합니다 오늘 많은 것을 알아보았습니다 시간을 내어 새 위젯 플랫폼을 탐색해보세요 앞서 소개한 영상을 참고해 영감을 얻고 iOS 및 macOS의 위젯의 외관을 새롭고 멋지게 꾸며보세요 마지막으로 위젯 데이터가 외부 소스 또는 다른 디바이스에서 업데이트 되면 푸시 알림을 추가하여 최신 상태로 유지해보세요 새로운 위젯의 기능과 환경 덕분에 아주 즐겁습니다 빨리 어디서든 위젯을 사용할 수 있기를 바랍니다 시청해 주셔서 감사합니다

    • 2:44 - Observe .widgetRenderingMode

      struct MostFrequentBeverageWidgetView: View {
          @Environment(\.widgetRenderingMode) var renderingMode
          
          var entry: Entry
          
          var body: some View {
              ZStack {
                  if renderingMode == .fullColor {
                      Image(entry.beverageImage)
                          .resizable()
                          .aspectRatio(contentMode: .fill)
                  
                      LinearGradient(gradient: Gradient(colors: [.clear, .clear, .black.opacity(0.8)]), startPoint: .top, endPoint: .bottom)
                  }
                  
                  VStack {
                      if renderingMode == .accented {
                          Image(entry.beverageImage)
                              .resizable()
                              .widgetAccentedRenderingMode(.desaturated)
                              .aspectRatio(contentMode: .fill)
                      }
                      
                      BeverageTextView()
                  }
              }
          }
      }
    • 6:08 - visionOS Widget Configuration

      struct CaffeineTrackerWidget: Widget {
          var body: some WidgetConfiguration {
              StaticConfiguration(
                  kind: "BaristaWidget",
                  provider: Provider()
              ) { entry in
                  CaffeineTrackerWidgetView(entry: entry)
              }
              .configurationDisplayName("Caffeine Tracker")
              .description("A widget tracking your caffeine intake during the day.")
              .supportedMountingStyles([.elevated])
              .widgetTexture(.paper)
              .supportedFamilies([.systemExtraLargePortrait])
          }
      }
    • 8:56 - LevelOfDetail - CaffeineTrackerWidgetView

      struct CaffeineTrackerWidgetView : View {
          @Environment(\.levelOfDetail) var levelOfDetail
          
          var entry: CaffeineLogEntry
      
          var body: some View {
              VStack(alignment: .leading) {
                  TotalCaffeineView(entry: entry)
      
                  if let log = entry.log {
                      LastDrinkView(log: log)
                  }
      
                  if levelOfDetail == .default {
                      LogDrinkView()
                  }
              }
          }
      }
    • 9:46 - LevelOfDetail - TotalCaffeineView

      struct TotalCaffeineView: View {
          @Environment(\.levelOfDetail) var levelOfDetail
          
          let entry: CaffeineLogEntry
      
          var body: some View {
              VStack {
                  Text("Total Caffeine")
                      .font(.caption)
      
                  Text(totalCaffeine.formatted())
                      .font(caffeineFont)
              }
          }
          
          var caffeineFont: Font {
              if levelOfDetail == .simplified {
                  .largeTitle
              } else {
                  .title
              }
          }
          
          var totalCaffeine: Measurement<UnitMass> {
              entry.totalCaffeine
          }
      }
    • 11:49 - Add .supplementalActivityFamilies

      struct ShopOrderLiveActivity: Widget {
          var body: some WidgetConfiguration {
              ActivityConfiguration(for: Attributes.self) { context in
                  ActivityView(context: context)
              } dynamicIsland: { context in
                  DynamicIsland {
                      DynamicIslandExpandedRegion(.leading) {
                          ExpandedView(context: context)
                      }
                  } compactLeading: {
                      LeadingView(context: context)
                  } compactTrailing: {
                      TrailingView(context: context)
                  } minimal: {
                      MinimalView(context: context)
                  }
              }
              .supplementalActivityFamilies([.small])
          }
      }
    • 12:27 - Add .activityFamily

      struct ActivityView: View {
          @Environment(\.activityFamily) var activityFamily
          var context: ActivityViewContext<Attributes>
          
          var body: some View {
              switch activityFamily {
              case .small:
                  ShopOrderSmallView(context: context)
              default:
                  ShopOrderView(context: context)
              }
          }
      }
    • 16:20 - Define relevance widget with RelevanceConfiguration

      struct HappyHourRelevanceWidget: Widget {
          var body: some WidgetConfiguration {
              RelevanceConfiguration(
                  kind: "HappyHour",
                  provider: Provider()
              ) { entry in
                  WidgetView(entry: entry)
              }
          }
      }
    • 16:41 - Implement RelevanceEntriesProvider

      struct Provider: RelevanceEntriesProvider {
          func placeholder(context: Context) -> Entry {
              Entry()
          }
          
          func relevance() async -> WidgetRelevance<Configuration> {
              let configs = await fetchConfigs()
              var attributes: [WidgetRelevanceAttribute<Configuration>] = []
              
              for config in configs {
                  attributes.append(WidgetRelevanceAttribute(
                      configuration: config,
                      context: .date(interval: config.interval, kind: .default)))
              }
              
              return WidgetRelevance(attributes)
          }
          
          func entry(configuration: Configuration,
                     context: RelevanceEntriesProviderContext) async throws -> Entry {
              Entry(shop: configuration.shop, timeRange: configuration.timeRange)
          }
      }
    • 21:13 - Handle push token and widget configuration changes

      struct CaffeineTrackerPushHandler: WidgetPushHandler {
          func pushTokenDidChange(_ pushInfo: WidgetPushInfo, widgets: [WidgetInfo]) {
              // Send push token and subscription info to server
          }
      }
    • 21:30 - Add pushHandler to WidgetConfiguration

      struct CaffeineTrackerWidget: Widget {
          var body: some WidgetConfiguration {
              StaticConfiguration(
                  kind: Constants.widgetKind,
                  provider: Provider()
              ) { entry in
                  CaffeineTrackerWidgetView(entry: entry)
              }
              .configurationDisplayName("Caffeine Tracker")
              .pushHandler(CaffeineTrackerPushHandler.self)
          }
      }
    • 22:29 - Push Notification Request Body

      {
          "aps": {
              "content-changed": true
          }
      }
    • 0:00 - Introduction
    • Learn about updates to WidgetKit including new ways to incorporate your app with the system, show relevant content in the Smart Stack, and keep your app up to date.

    • 1:03 - Widgets in new places
    • Widgets have new styling options and are available in new places. Check out tips to make your widgets look great with accented rendering mode. Widgets are available in more places, including visionOS 26 and CarPlay. Widgets on visionOS 26 can be added to rooms and pinned to surfaces. These widgets can be customized to support different mounting styles, textures, and level of detail based on proximity. CarPlay and macOS 26 now support Live Activities. Controls are available on macOS Tahoe and watchOS 26.

    • 15:31 - Relevance widgets
    • Relevant widgets show up in the Smart Stack on watchOS 26 when they’re most relevant based on people’s routines, location, and more. These widgets show up in the Smart Stack only when they’re relevant, and multiple instances can show up at the same time, like for overlapping calendar events or happy hours. Build relevant widgets by specifying when the widget is most relevant, like at a particular time or type of location.

    • 18:12 - Push widget updates
    • Widgets across all WidgetKit platforms can now be updated by push updates through APNS. There are multiple tools to keep widgets up to date, and the best tool for each use case is determined by how the data for your widget is updated. Timelines are good for regularly updating data. Changes driven by interaction in an app should reloadAllTimelines. For synchronization between devices, or external data changes, like from a server, use widget push updates. Push updates for widgets help keep widgets more up to date, but aren’t a direct replacement for other notification experiences. Consider whether a User Notification, Live Activity, or widget is best for each use case.

Developer Footer

  • 비디오
  • WWDC25
  • 위젯의 새로운 기능
  • 메뉴 열기 메뉴 닫기
    • 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. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침