들어가기 전에
개-하! 돌아왔습니다 덥덥 2탄!!
원래 목표하던 나머지 세션들 다 듣고 올릴라 그랬는데,,! 역시나 덥덥 주간 끝나자마자 듣는 속도가 확실히 느려지기도 했고,, (무섭도록 잘되어있는 메타 인지..) 무엇보다 동료분이 “덥덥 추천 2탄 언제 올라와요???” 라고 물어봐주셔서, 이런 메모장이라두 기다려주시는 분이 계시는군…하구 일단 또 날라왔읍니다.
지난 [WWDC] WWDC23 추천 세션들 — 1탄과 분류 기준은 아래와 같이 동일하구, 마찬가지로 각 세션에 대한 메모는 overview 나 핵심적인 내용을 담고 있다기 보다는,, (물론 그런것도 있지만요!) 그냥 제가 인상 깊게 느꼈던거나 생각 위주로 메모해뒀습니다잇.
⭐️ 따로 정리해볼만 함. 다시 보면 좋음.
❤️ 인터레스팅
👀 그냥저냥 봄
그럼 시작해보져! ㄱㄱ
Add SharePlay to your app 👀
2023 let us: Go! Summer 찍먹톤 참가 후기 보다가 영업당해서 홀릿듯이 시청
오 iOS 17 부터는 에어드롭 통해서도 셰어 플레이도 된다구? 원래는 페이스타임이랑 메시지에서만 됐었는디?
근데 사실 이전에도 셰어 플레이 써본적 없긴함..ㅎ
Meet Push Notifications Console ❤️
push notification console 에서는 APNs 와 상호작용하기 위한 다양한 툴을 제공!
아아니~~ 이걸 지금 지원해줘버린다구~~? 지금이라도 해주는거에 감사해야하나..?? 이제 서드 파티 push notification 테스트는 다 죽나여?
저전력 모드일때 푸쉬 안오는거 첨 알았네;; 홀딩쓰..
푸쉬 상태나 실패 이유 등 자세히 알려줘서 좋다 굿굿~~ token 도 바로 생성해볼 수 있구만~~
Expand on Swift macros ⭐️
다른 언어에서 사용하는 매크로와는 디자인이 다르다구? 자신감 대단한디~
freestanding macro 는 코드 내에서 다른 요소를 대신하여 사용됨. 항상 # (pound) 기호로 시작함.
attached macro 는 코드의 declaration 에서 속성 (attribute) 으로 사용됨. 항상 @ (at) 기호로 시작함.
Swift 는 이미 # 및 @ 기호를 사용해서 특별한 컴파일러 동작을 나타내는데, 매크로는 이를 확장 가능하게 만듦
매크로를 호출을 보면 -코드에서 해당 매크로를 추출해서 -이에 대한 구현을 포함하는 특수 컴파일러 플러그인으로 보내내고 -플러그인은 보안 샌드박스에서 별도로 실행되어 매크로를 처리하고 이에 의해 생성된 새로운 코드 조각인 “expansion” 을 반환 -Swift 컴파일러는 해당 expansion (확장) 을 프로그램에 추가하고, 코드와 함께 컴파일
role 은 매크로를 적용하는 위치와 방법, 확장되는 코드의 종류, 해당 확장이 삽입되는 위치 등등을 제어하는 일 등을 하는 매크로에 대한 일련의 규칙임. 총 7개의 role 중 freestanding macro 를 만드는게 2개, attached macro 를 만드는게 5개 있음. 각각에 대해 자세히 알아보기 위해서는 6:18부터
Write Swift macros 만 봤을때는 매크로.. 과연 내가 작성해서 잘 쓸까? 싶었는데, 여기서 role 별 예시 들어주는거 보니까 확실히 쓸만한 일들이 생기겠다 싶었음.
컴파일러에서는 매크로가 사용되는 것을 볼 때, 별도의 프로세스에서 플러그인을 시작하고 매크로를 확장하도록 요청함. 매크로의 선언은 다른 API 와 함께 일반 라이브러리에 들어가지만, 매크로 구현은 별도의 컴파일러 플러그인 모듈에 들어감. #externalMacro 가 이 관계를 정의하는데, 여기서 컴파일러가 시작해야하는 플러그인과, 해당 플러그인 내부 type 의 이름을 지정해서 둘 사이의 링크를 만듦.
SwiftSyntax 는 Swift 소스 코드를 구문 분석, 검사, 조작 및 생성하는데 도움이 되는 패키지. SwiftSyntax 는 소스 코드를 특별한 트리 구조로 나타냄. 이에 대한 자세한 정보는 Wirte Swift Macros 세션 보든가, SwiftSyntax 패키지 문서 봐라.
SwiftSyntaxMacros 는 매크로 작성에 필요한 프로토콜과 타입을 제공하는 모듈.
SwiftSyntaxBuilder 라는 새로 생선된 코드를 나타내는 구문 트리를 구성하기 위한 편리한 API 를 제공. 이건 제외하고 매크로를 작성할 수도 있지만, 매우 편리하므로 사용하는게 좋음
Swift 목표 중에 하나는, 매크로 작성시에서부터 에러를 감지하고 뱉도록 하는 것. Diagnostic 이라는 타입의 인스턴스를 만듦으로써 더 복잡한 오류를 생성할 수 있음. 에러에서 Fix-It 을 추가할 수도 있음.
여기까지 듣고나니.. 흠.. 날짜와 시간을 삽입하는 매크로를 작성하고싶다! 라는 생각이 들수도 있는데, 그러지 말길 ㅎㅎ 매크로는 컴파일러가 제공하는 정보만 사용해야함. 컴파일러는 매크로 구현이 순수 함수이며, 제공된 데이터가 변경되지 않는 경우 확장도 변경할 수 없다고 가정함. 이를 우회하면 일관되지 않은 동작이 나타날 수 있음. 따라서 컴파일러 플러그인은 매크로 구현이 디스크 파일을 읽거나 네트워크에 접근하지 못하도록 샌드박스에서 실행됨. 하지만 샌드박스에서 실행하는 것이 위에서 말한 규칙을 위반하는 동작을 모두 막을 수는 없으므로 하지마셈
매크로 플러그인은 그냥 일반적인 Swift 모듈임. 이는 일반적인 단위테스트를 작성할 수 있고, 해야한다는 것을 의미. TDD 는 매크로 개발에 매우 효과적인 접근 방식.
매크로를 사용하면 작은 사용처가 크고 복잡한 코드 조각으로 “확장” 하는 새로운 언어 기능을 설계해서 boilerplate 를 줄일 수 있음.
일반적으로 라이브러리에서 다른 API 와 함께 매크로를 선언하지만, 실제로는 secure sandbox 에서 Swift 코드를 실행하는 별도의 플러그인에서 매크로를 구현함
Wirte Swift Macros 세션에서는 매크로 개발 도구 및 매크로 패키지 템플릿으로 작업하는 방법, SwiftSyntax 트리를 검사하고, 트리에서 정보를 가져오는 방법, 단위 테스트를 중심으로 매크로 개발 워크 플로우를 구축하는 방법을 보여줌
Debug with structured logging ❤️
새로운 디버깅 콘솔 등장!!
console 에 로그 찍히는게 separator 로 나눠서 보여진다?! 그리고 앞에 표현하는 내용 자체도 훨씬 깔끔해짐 (metadata 접두사를 없앤다든지). 색깔도 입혀주네 얼씨구???
로그 정보도 자세해져서, 로그의 Type (ex. info), TimeStamp, Library, Subsystem, Category, Call site 의 정보를 볼 수 있음. 보고 싶은 meta data 정보만 필터링 할 수도 있음.
log 필터링도 좋아짐
로깅을 위해서 OsLog 의 Logger 를 사용해라. 그러면 위에 향상된 Debug Console 과 함께 디버깅 경험을 크게 향상시킬 수 있음. 흠 얘네는 iOS 14 이상이군
lldb 커맨드에서는 Do What I Mean Print 명령어가 생김. 이를 통해 코드의 다양한 expression 을 evaluate 하는 동시에, 가장 빠른 방법으로 결과를 반환함으로써 시간을 절약할 수 있음.
명령어로는 dwim-print 인데, 너무 기니까 그냥 이전의 p 와 po alias 를 dwim-print 로 대체함. 이전의 v, p, expr 대신 p 를 사용하고, 이전의 vo, po, expr-o 대신 po 를 사용하면 의도한 출력을 얻기 위해서 여러 명령어를 살펴가며 사용할 필요 없음.
Meet ActivityKits ❤️
Live Activity 는 이벤트 또는 작업 진행 상황을 추적할 수 있는 몰입적이고 한눈에 볼 수 있는 방법. 별도의 시작과 끝이 있으며, 백그라운드 런타임에서 실시간 업데이트를 제공하거나 푸시 알림을 사용 (“liveactivity” push type 사용) 하여 원격으로 업데이트를 제공할 수 있음.
Live Activity 는 Dynamic Isaland 가 있을때 훨씬 더 몰입적임.
iOS 17에는 lock screen 과 dynamic island 외에도 StandBy 상태에서도 나타남. 또한 iPad 에서도 live activity 가 지원됨.
Live Activity 는 ActivityKit 프레임워크를 통해 앱이 라이프사이클을 요청, 업데이트 및 관리할 수 있도록 지원함. Live Activity 의 life cycle 은 네 가지 주요 단계로 나뉨. 1. 활동 요청 -2. 최신 콘텐츠로 업데이트 -3. 활동 종료 등의 상태 변화에 반응하기 위해 활동 관찰 -4. 활동 종료
15:18 에 dynamic island 구역별로 설명해주는데 흥미롭군..
Update Live Activities with push notifications ❤️
라이브 활동은 진행 중인 활동에 대한 간편한 정보를 누군가에게 표시하는 훌륭한 방법. ActivityKit을 통해 앱에서 라이브 활동을 시작, 업데이트 및 종료할 수 있음. 그런 다음, WidgetKit과 SwiftUI를 활용하여 사용자에게 정보를 표시하는 UI를 구축 가넝
우선 앱과 서버가 Apple Push Notification 서비스와 상호 작용하는 방법을 이해하는 것이 도움이 됨.
- 새로운 라이브 액티비티가 시작되면, ActivityKit은 Apple Push Notification 서비스(간단히 APNs라고도 함)로부터 푸시 토큰을 얻음. 이 푸시 토큰은 요청한 각 라이브 액티비티마다 고유함.
- 따라서 앱은 푸시 업데이트를 보내기 전에 이 푸시 토큰을 서버로 전송해야 함.
- 그런 다음, 라이브 활동을 업데이트해야 할 때마다 서버는 토큰을 사용하여 푸시 요청을 APNs로 보냄
- 마지막으로, APNs가 페이로드를 디바이스로 보내고, 이로 인해 위젯 익스텐션을 활성화하여 UI를 렌더링
이 새로운 기능을 지원하기 위해, APNs는 새로운 liveactivitypush
타입을 도입함. 이 푸시 타입은 토큰 기반으로 APNs에 연결된 서버에만 사용 가능함.
앱에서 푸시 업데이트를 받을 수 있도록 하려면 Activity.request 메서드의 pushType 에 .token
을 세팅. 이렇게 하면 ActivityKit 이 라이브 액티비티가 생성될 때 푸시 토큰을 요청하도록 알 수 있음.
액티비티가 생성된 후에는 앱이 푸시 토큰을 서버로 전송해야하는데, activity.pushToken
처럼 pushToken 프로퍼티를 통해 동기적으로 푸시 토큰에 접근 할 수 있음. 하지만 액티비티 생성 직후에 접근하면 대부분의 경우 nil 일 것이기 때문에, 즉시 접근하지 않아야함, 왜냐하면 푸시 토큰 요청은 비동기적인 프로세스이기 때문.
푸시 토큰을 올바르게 처리하는 방법은 먼저 비동기 Task를 생성하고, pushTokenUpdates 비동기 시퀀스를 관찰하는 for-await 루프를 시작하는 것. 이는 첫 번째 푸시 토큰뿐만 아니라 후속 푸시 토큰 업데이트도 처리할 수 있음.
푸시 업데이트를 보내려면 APNs에 HTTP 요청을 보내야하는데, 요청은 APNs 헤더와 APNs 페이로드로 구성됨. 일반적인 HTTP 헤더에 추가로 아래 세 가지 헤더를 제공해야 함.
- apns-push-type:
liveactivity
- apns-topic:
<BUNDLE_ID>.push-type.liveactivity
- apns-priority:
5
or10
(5는 낮은 우선 순위, 10은 높은 우선 순위. 우선 순위에 따라 배터리 수명에 영향을 미치므로 긴급하지 않은 경우에는 낮은 우선순위를 우선적으로 고려해야함)
또한 APNs 는 세 개의 필드로 구성된 페이로드를 보낼 것임.
- timestamp:
<1970년 이후로 초 단위로 된 시간 간격
(항상 최신 콘텐츠 상태를 렌더링하기 위해 사용) - event:
update
orend
(Live Activity에서 수행하려는 동작으로, 초기 APNs 요청에서는 "update"로 설정 필요) - content-state:
<디코딩할 수 있는 JSON 개체>
command line 을 통해 서버를 수정하지 않고도 푸시 요청을 직접 터미널에서 APNs로 보낼 수도 있음
이 분도 마지막에 큐브 맞춰버리시네.. 애플 개발자 필수 덕목인가?
Get started with privacy manifests ❤️
타사 SDK 에서 수집하는 개인 정보에 대한 정보를 알아내는 것 어려웠음. 이제 Privacy manifest 를 통해 타사 SDK 개발자는 자신들의 privacy practicies 에 대한 정보를 제공할 수 있음!
그리고 새로운 privacy report 는 이 모든 정보를 한곳으로 가져옴. Xcode Organizer 에서 우클릭을 통해 Generate Privacy Report 를 하면 앱 프로젝트의 모든 privacy manifest 를 통합하고, 선언된 데이터 사용을 요약하는 개인 정보 보고서를 생성 가능
또한 사용자의 허락 없이 우리 또는 서드파티 SDK 에서 추적하는 것을 방지하고자, Privacy manifest 에는 tracking domain 이 포함됨. 사용자가 추적 권한을 제공하지 않는 경우, iOS 17 은 앱에 포함된 tracking domain 에 대한 연결을 자동으로 차단함. 이렇게 우발적인 연결을 방지함으로써, 이 기능은 허가 없이 사용자를 추적하지 않으려는 의도를 유지하는데 도움이 됨.
사용자가 앱에 추적 권한을 부여했는지 여부에 관계 없이 어떠한 경우든 핑거 프린팅은 허용되지 않음. 핑거 프린팅은 device 또는 user 를 식별하기 위해서 장치의 신호 (signal) 를 사용함.
애플 플랫폼에는 핑거 프린팅에 오용될 가능성이 있는 기존 API 가 있는데, 핑거 프린팅을 피하면서 중요한 사용 사례 (ex. 디스크를 쓰기 전에 디스크 공간이 충분한지 확인한다든지..) 를 지원하기 위해, Required reason API 라고 하는 API 의 새로운 범주가 있음. 이런 API 목록들과 승인된 이유들은 Apple developer documentation 에 있음. 앱과 SDK 는 승인된 이유에 대해서만 Required reason API 에 접근 가능. Privacy manifest 에 이 정보가 포함됨.
앱 생태계를 살펴보니 사용자 개인정보 보호에 특히 큰 영향을 미치는 타사 SDK가 몇 가지 확인됨. 이러한 SDK를 개인 정보 보호에 영향을 주는 SDK라고 하는데, 이러한 타사 SDK 및 향후 업데이트 목록은 Apple 개발자 문서에 게시됨.
⭐️ 2023년 가을부터 앱스토어는 개인정보 보호에 영향을 미치는 SDK 를 포함하는 새로운 / 업데이트되는 앱을 확인함. 개인 정보 보호에 영향을 미치는 SDK에 서명 및 개인 정보 매니페스트가 포함되어 있지 않은 경우, Apple은 앱 개발자에게 information 이메일을 보냄. Apple은 승인된 이유를 선언하지 않고 Required Reason API에 액세스하는 앱에 대한 메일도 보냄. 2024년 봄부터 이러한 기능이 예상되며 앱 리뷰의 일부가 될 것임. 따라서 앱 스토어에 새 앱과 업데이트된 앱을 제출하려면 먼저 문제를 해결해야 함.
- 앱 개발자: 타사 SDK 개발자에게 SDK Privacy manifest 매니페스트를 요청. 앱을 제출할 때는 항상 Xcode privacy report 를 참고해서 Nutrition Label 을 최신 상태로 유지해야함.
- SDK 개발자: 서명 및 매니페스트를 채택해야함
- 모든 개발자: 앱 또는 SDK의 Privacy manifest 에서 tracking domain 및 Required Reason API 사용을 문서화하고 선언해야함.
새로운 Privacy manifest를 통해 사용자에게 정확하고 완전하며 명확한 개인 정보를 제공하는 것이 그 어느 때보다 쉬워질 것임.
아래 목록들을 올해 말에 게시할 예정 (아니~~ 이미 게시되어있어야하는거 아님??)
- privacy 에 영향을 미치는 SDK (사용자 privacy에 특히 큰 영향을 미치는 타사 SDK) 목록
- 허용된 이유를 선언해야 하는 “required reason” API 목록
- covered APIs 를 호출하는 새로운 이유를 제안하는 개발자 피드백 양식
- 서명, privacy manifests 가 언제 필요한가, 이에 대한 이점과 세부 정보, 그리고 언제 필요한 시기의 이점과 세부 정보에 대한 추가 문서
참고 — What’s new in privacy on the App Store
Ready, set, relay: Protect app traffic with network relays 👀
앱은 릴레이(relay)를 사용하여 모든 사용자에 대해 강력한 개인 정보 보호를 제공할 수 있음. 릴레이(relay)는 최신 전송 및 보안 프로토콜을 사용하는데, 이 프로토콜의 종류에는 MASQUE 와 Oblivious HTTP 라는 두가지 타입이 존재함.
MASQUE 릴레이는 백엔드 서버를 수정하지 않고도 릴레이를 통해 TCP 또는 UDP 연결을 보낼 수 있음. 릴레이 서버를 연결하여 IP 주소와 브라우징 활동을 결합하여 사용자의 상세 프로필로 만들 수 없도록 할 수 있는데, 이것이 iCloud Private Relay의 핵심 기술임. MASQUE 릴레이는 모든 트래픽을 프록시로 보호하기 위해 TLS 1.3을 사용함. MASQUE는 최신 전송 프로토콜인 QUIC과 HTTP/3를 사용하여 하나의 터널을 통해 많은 연결을 효율적으로 프록시 및 다중화함. 그리고 QUIC가 네트워크에서 차단되는 경우 HTTP/2를 사용하여 대체 가능.
만약 앱이 익명 메트릭 보고, 데이터베이스 조회 또는 DNS 쿼리와 같이 다른 요청과 관련되지 않는 개인 정보 보호를 보장하고 싶은 HTTP 요청을 보낸다면 Oblivious HTTP를 사용할 수도 있음. Oblivious HTTP를 사용하면 단일 릴레이 홉으로 훌륭한 성능과 개인 정보 보호를 얻을 수 있음. MASQUE 릴레이와 달리, Oblivious HTTP는 임의의 서버와 작동하지 않음. 서버는 명시적으로 Oblivious HTTP를 지원해야 함.
새로운 ProxyConfiguration 클래스를 사용하여 Network 프레임워크, URLSession 및 WebKit에서 릴레이를 정의할 수 있음. ProxyConfiguration 객체 내에서는 다섯 가지 다른 프로토콜을 기반으로 프록시를 정의할 수 있음.
- MASQUE Relays
- Obilvious HTTP
- Secure HTTP CONNECT
- HTTP CONNECT
- SOCKSv5
iOS 17에서는 앱에 릴레이를 추가하는 것 외에도 전체 기기에 대해 릴레이를 구성할 수 있음. 기업에서는 VPN의 사용을 릴레이로 대체하여 관리가 용이하고 원활한 사용자 경험을 제공할 수도 있음.
Beyond scroll views 👀
올해 SwiftUI 는 ScrollView에서 관리하는 content offset 에 영향을 주고, 반응(react)하는 다양한 방법을 도입했음. safeAreaPadding(_:) 이 새로 생겼음. 콘텐츠에 padding을 추가하는 대신 safe area에 padding을 추가함.
contentMargins API 도 생김. 이를 통해 ScrollView의 콘텐츠와 스크롤 indicator 를 별도로 여백을 지정할 수 있음.
기본적으로, ScrollView는 표준 감속률과 스크롤의 속도를 사용하여 스크롤이 종료될 목표 콘텐츠 오프셋을 계산함. 이때 스크롤뷰의 크기나 콘텐츠와 같은 요소는 고려하지 않음.
하지만 이러한 요소가 중요할 때도 있는데, SwiftUI에서는 scrollTargetBehavior(_:) modifier를 사용해서 ScrollView가 목표 콘텐츠 오프셋을 계산하는 방식을 변경할 수 있음. .scrollTargetBehavior(.paging)
처럼 사용해서 ScrollView 를 한 번에 한 페이지씩 스와이프되게 할 수 있음. 인자로 들어가는 값은 scrollTargetBehavior 프로토콜을 준수하는 타입인데, 사용자가 해당 프로토콜을 준수하는 유형을 직접 만들어서 custom 할 수도 있음.
원래 기기의 크기에 비례해서 무언가를 할때 GeometryReader를 사용해야 했지만, 올해 containerRelativeFrame 라는 새로운 API 를 발표함. 이를 통해 뷰의 프레임을 컨테이너에 상대적으로 얻을 수 있음.
scrollIndicators API 를 통해 스크롤 인티케이터의 visibility 를 세팅할 수 있는데, 마우스를 사용할때 scroll indicator 가 없으면 스크롤링이 어렵거나 불가능할 수 있음. 따라서 기본적으로 트랙패드 등의 상황에서는 인디케이터를 숨기지만, 마우스가 연결되어 있는 경우 인디케이터를 표시하도록 설정되어 있음. 물론 .never 를 설정해서 어떤 상황에서든 숨길수도 있음.
scrollPosition 이라는 modifier 도 새로 나왔는데, 이는 전달받은 id 가 있는 곳의 위치를 알려줌.
ScrollTransitions 도 SwiftUI에서 새롭게 제공되는 API로, ScrollView 내에서 뷰의 위치에 따라 시각적으로 뷰를 변경할 수 있도록 도와줌. 일반적인 transition과 매우 유사함. ScrollTransitions는 VisualEffect라는 새로운 프로토콜과 함께 작동함.
What’s new in App Clips 👀
앱 클립(App Clips)은 사용자가 앱을 다운로드하고 설치하지 않고도 앱의 기능을 시도할 수 있는 앱의 경량 버전임.
앱 클립(App Clips) 경험을 개선하기 위해 아래와 같은 세 가지 새로운 기능을 도입했음
- 새로운 크기 제한
iOS 17에서는 더 다양한 앱 클립 경험을 제공하기 위해 디지털 호출을 위한 새로운 50MB 크기 제한이 도입됨.
만약 NFC 태그나 앱 클립 코드를 통한 물리적 호출을 활용하려면, iOS 16에서 도입된 15MB 제한을 준수해야 함. 이는 사용자가 이동 중인 경우 빠른 사용자 경험을 보장하기 위한 것.
iOS 15 이전 버전을 대상으로 하는 경우, 원래의 10MB 제한이 여전히 적용.
2. Default 앱 클립 링크를 사용하여 앱 클립을 구성하는 새로운 방법
App Clip 호출은 universal 링크로 구동됨. 이를 위해서는 해당 메타데이터를 호스팅할 웹사이트를 제공해야 함. 이렇게 하면 Safari가 App Clip을 인식하고 해당 웹사이트의 URL을 통해 App Clip을 호출할 수 있게 됨.
기본 App Clip 링크는 기본 App Clip 경험을 호출하는 데 사용되는 새로운 방법임. 이러한 링크는 Apple에서 자동으로 생성되며, App Store Connect에서 App Clip을 게시할 때 자동으로 생성됨 (모두 appclip.apple.com 도메인을 가짐). iOS 16.4부터 지원.
3. 앱에서 직접 앱 클립을 호출할 수 있는 기능
어떤 앱에서든 App Clip을 호출할 수 있게 됨. iOS 17 부터 지원.
LPMetadataProvider 요청을 통해 메타데이터를 검색한 후, 해당 메타데이터를 LPLinkView에 전달하여 미리보기를 렌더링할 수 있음.
Fix failures faster with Xcode test reports 👀
테스트 리포트가 좋아졌다
- 높은 수준의 요약 정보를 제공하고,
- 중요 패턴을 강조 표시하고,
- 테스트 activity, 실패 정보, 스크린 샷등을 볼 수 있는 단일 위치를 제공하고,
- UI 테스트 디버깅 도구를 개선해서 더 풍부한 오류 정보를 제공함.
Build accessible apps with SwiftUI and UIKit ❤️
SwiftUI 의 AccessibilityTrait 에 toggle element 를 나타내는 isToggle 속성이 추가됨. 이에 맞는 적절한 힌트도 제공함. UIKit 에서도 이에 대응하는 UIAccessibilityTraits 의 toggleButton 이 추가됨.
새로운 AccessibilityNotification 는 Announcemet
, LayoutChanged
, ScreenChanged
, PageScrolled
네가지 알림을 만드는 방식을 제공함 (아마 UIKit 의 UIAccessibility.Notification
과 대응되는 건듯?)
accessibilitySpeechAnnouncementPriority 를 통해 이제 알림의 우선순위를 정할 수 있음. High, Default, Low 로 나뉘어서, 높은 우선순위는 낮은 우선순위 중간에 끼어들 수 있음. UIKit 에서는 NSAttributedString
의 attribute 로 NSAttributedString.Key.UIAccessibilitySpeechAttributedAnnouncementPriority
를 설정해주면 됨.
이제 assistive 가 활성화된 경우에도 UI 요소를 확대 / 축소 할 수 있음. SwiftUI 에서 accessibilityZoomAction
을 통해 이를 달성 가능. UIKit 에서는 accessibilityTraits 에 .supportZoom
을 추가하고 accessibilityZoomIn
, accessibilityZoomOut
함수를 override 해서 구현.
이제 VoiceOver 활성화 사운드를 스킵하고, 바로 액션을 직접 전달 할 수도 있음. SwiftUI 에서 accessibilityDirectTouch(options: .slientOnTouch)
로 구현. UIKit 에서는 accessibilityTraits
를 .allowsDirectionInteraction
을 설정하고 accessibilityDirectTouchOptions
을 .slientOnTouch
로 설정하면 됨.
SwiftUI 에서 접근성 용도의 Shape 를 설정할 수도 있음. .contentShape(.accessibility, Circle())
같이 첫번째 인자에 접근성용 Shape 설정 가능.
새로운 accessibilityValueBlock
라는 accessibility block API 가 등장. 이를 통해 값을 직접 저장하는 대신 속성이 필요할 때마다 평가되는 클로저를 제공할 수 있음. 이 클로저는 VoiceOver 커서를 새 요소로 이동할 때마다, 클로저로 설정된 속성을 찾고 다시 evaluate 됨. viewDidLoad 메서드에서 클로저를 생성해서 작업을 단순화할 수 있음. 이를 통해 접근성 속성을 훨씬 쉽게 유지, 관리 가능
마무리
아래 세션들도 더 보고 싶은데,, 과연 3탄은 나올 수 있을까요? ㅎㅎ 그건 장담 못하지만,, 꼭 봐야한다!!! 하는거 있으면 추천해주세여!!! 그럼 20000!
Wind your way through advanced animations in SwiftUI
Meet the App Store Server Library
Generalize APIs with parameter packs
Spotlight your app with App Shortcuts
Build programmatic UI with Xcode Previews