
spatical computing을 위한 앱을 만들 때 SwiftUI를 활용하는 것은 최상의 방법이다.
다양한 여러 기술들이 SwiftUI로만 가능하다.
버튼, 토글, 탭 뷰와 같은 핵심적인 building block들은 core 앱들에 사용된다.
FreeForm에서는 3D 보드 제작이 가능하다.
버튼은 다양한 플랫폼에서 유사한 동작을 하며 존재하지만, 몇가지 핵심적인 차이점도 존재한다.(2분 41초부터 설명 영상 참고)
SwiftUI에는 3D environment를 위한 새로운 API들도 포함되었다.
SwiftUI 앱은 scene으로 만들어져있고,
scene은 view들로 만들어져있다.
Scene은 하나 이상의 window를 표시하기 위한 WindowGroup과 같이 앱의 top-level entry point를 형성한다.
Spatical Computing에는 앱을 구성하는 3가지 종류의 scene이 있다.
Windows, Volumes, Full Spaces다.
window는 익숙하고 전통적인 interface이다.
ex. 사파리, freeform, mindfulness
새로운 3D window style로 Bounded 공간 안에서 오브젝트를 전시하거나 경험을 제공하기 위해 사용된다.
새로운 immersive app 만드는 방식.
앱이 완전한 컨트롤을 가지며, 모든 앱들의 윈도우를 숨기고 콘텐츠를 어느 곳에든 배치할 수 있게 해준다.
이 세가지는 같이 사용할 수 있도록 디자인 되었다.
각각은 다른 use case를 위해 목적성 있게 설계 되었다.
그래서 이 목적에 맞게 섞고 매칭할 수 있다.
간단한 3D preview를 보여주기 위해 window에서 volume을 나타낼 수 있고
사람들이 model에 완전히 몰입할 수 있도록 Volume에서 Full Space를 보여줄 수도 있다.
사람들이 독립적으로 창을 열고 닫을 수 있게 앱을 분리된 조각으로 정렬할 수 있는 최상의 방법으로 같은 타입의 여러 scene들을 사용할 수도 있다.
각각의 scene type에 대해 더 알아보자.
window를 보여주기 위해 다른 플랫폼들처럼 WindowGroup을 이용해준다. WindowGroup을 사용함으로 인해 macOS나 iPadOS처럼 자동적으로 여러 window를 사용할 수 있게 된다.
Window는 앱의 콘텐츠를 잘 볼 수 있게 함과 동시에 사람들이 주변을 볼 수 있도록 아름다운 glass background에서부터 시작된다.
window안에서는 다른 플랫폼과 마찬가지로 navigation container도 사용가능하다.
예를 들면, 여러 top-level component들을 정렬하기 위해 TabView를 사용할 수 있고
앱의 hireachy를 정렬하기 위해 iPadOS의 구조와 유사하게 Navigation Stack과 split view도 사용할 수 있다.
List는 정보를 정리하기 위한 powerful한 도구이다.
마찬가지로, 앱에 interactivity도 추가할 수 있다.
이 앱에 TabView 적용
TabView는 새롭게 등장한 SwiftUI의 'Ornaments'에 대한 아주 좋은 예시이다.
Ornaments는 앱의 window와 관련하여 accessory view를 배치할 수 있게 해주고, window 영역 밖을 확장해준다.
그래서 윈도우 자체에는 속하지 않는 추가적인 컨트롤들을 배치하고 앱 콘텐츠를 방해하지 않는 것에 적합하다.
그리고 modifier를 통해 ornament를 직접 만들수도 있다.
다시 Glass에 대한 설명
glass는 새로운 material로 디자인 되어 시각적 위계를 표현하는데 도움을 준다.
Glass는 어떠한 환경에서 사용되던 읽기 쉽기 위해 환경에 자동적으로 적응한다.
이 말인 즉슨, 이 플랫폼(Vision Pro)에서는 dark, light appreance가 없다는 것이다. Material이 이 역할을 해준다.
material을 통해 어떻게 더 읽기 쉬운 콘텐츠를 만들 수 있을지 알아보자.
Stats grid section은 현재 title과 gird로 구성된 VStack으로 만들어져 있다.
material background를 이용해서 이 카드가 pop 하는 것처럼 만들어보자.
Fun Facts 카드에도 동일한 효과 적용.
Func Facts 현재 상태
Learn more text의 무게감이 무거워보인다.
secondary foreground style을 적용한다.
Spatial Computing에서는 새로운 interaction 방식들이 등장했다.
가장 흔한 건 보는 것이고, tap하기 위해 간접적인 pinch gesture와 함께 많이 사용된다.
또한 손을 통해 직접적인 Interaction도 가능하다.
그리고 연결된 트랙패드 혹은 hand gesture를 통해 가장 정확한 Input인 pointer를 이용할 수도 있다.
이 시스템은 하드웨어 키보드를 연결할 수도 있으며, 생산성을 위해 keyboard shortcut, Focus, key modifier도 지원한다.
그리고 VoiceOver와 Switch Control과 같이 다른 플랫폼에서도 사용가능한 Accessibility도 지원한다.
SwiftUI에서 이미 사용하고 있는 gesture들은 TapGesture와 DragGesture와 같이 자동적으로 각각의 interaction에 맞게 적응된다.
그리고 3D interaction을 위해 새로운 gesture들도 등장하게 되었다.
그리고 마찬가지로 다른 모든 플랫폼에서 사용중인 accessibility API들도 잘 작동한다.
그리고 많은 기능들이 이 플랫폼을 위해 reimagined 되었는데, Dwell Control 같은 경우에는 눈으로만 앱을 Navigate 할 수 있게 한다.
accessibility 관련해서 더 알고 싶다면 이 영상을 보도록.
interaction이 일어난 것을 쉽게 알 수 있고 spatial computing에 직관적인 도구는 Hover effect다.
예를 들면 interative view를 보기만 해도 system은 view에 미묘한 하이라이트를 표시함으로써 당신이 상호작용하고 있다는 피드백을 제공해준다.
이 효과는 각 Input의 형식에 대해 자동으로 추가되어 사용자에게 interaction이 일어나고 있다는 확신을 준다.
Hover effect는 반응적인 피드백을 주는 것 뿐만 아니라 타겟팅을 도와주기 때문에 효과적이다.
그리고 Hover effect는 사람들이 정확히 어딜 보고 있는지에 대한 반응을 제공할 수 있는 유일한 방법이다.
이러한 효과들은 사람들의 privacy도 물론 지켜준다.
Hover effect는 버튼, 토글, 텍스트 필드 같은 대부분의 컨트롤들에 자동적으로 적용된다.
SwiftUI에서 제공하는 내제된 스타일을 사용한다면 자동적으로 이러한 효과를 누릴 수 있다.
커스텀된 컨트롤이나 스타일을 사용한다면 hover effects를 추가하도록!
Fun Fact card에 custom 버튼 스타일을 사용하고 있기에 hover effect를 따로 추가해야만 한다.
현재 버튼 스타일은 그저 패딩을 추가하고 버튼의 라벨에 대해 커스텀 배경만 제공해주고 있다.
이를 고치기 위해 hoverEffect modifier를 추가해준다.
window 앱을 더 기깔나게 만들고 싶다면 이 영상을 보도록.'
volume은 모든 각도에서 보기 위해 디자인 된 것이다.
앱에 volume을 추가하기 위해서는 간단히 volumetric widow style을 추가해주면 된다.
또한 콘텐츠에 맞게 window의 default 3D를 지정할 수도 있다.
3D 지구 모델을 display하기 위해 RealityKit의 새로운 Model3D API를 사용한다. 이 API를 통해 손 쉽게 앱에 3D 콘텐츠를 추가할 수 있다.
Model3D는 image와 비슷하며 아름다운 3D 콘텐츠를 손쉽게 불러오고 display할 수 있다.
Image와 다르게 3D 콘텐츠는 불러오고 띄우는데 시간이 걸릴 수 있기 때문에 Model3D는 항상 비동기적으로 로딩한다.
AsyncImage view와 비슷하게, Model3D view는 placeholder를 자동적으로 그려준다.
또한 full control을 가져서 own placeholder를 표시해 줄 수도 있다.
Model3D는 다른 SwiftUI 뷰와 같기 때문에 3D를 SwiftUI 앱에 가져오는 것은 이미 익숙한 방식과 동일하고, visual effect, gesture등을 자연스럽게 확장할 수 있다.

예를 들면 이렇게 ZStack을 layout으로 사용할 수 있다.
ZStack과 같은 레이아웃은 너비 및 높이와 마찬가지로 컨텐츠의 깊이를 자동으로 인식한다.
그리고 모델 3D는 기본적으로 2D 이미지처럼 3차원 모두에 맞게 크기가 조정된다.
실제로 전체 레이아웃 시스템은 컨텐츠의 깊이와 사용 가능한 공간을 파악하고 그에 따라 레이아웃을 조정한다.
그리고 이런 깊이를 조정하는 modifier가 새로 등장했다.
volume은 모든 각도에서 보여야하므로, 모든 면에서 어떻게 보이는지 신경써야한다.
마지막으로 컨트롤이 훌륭하고 grounded됨을 느낄 수 있도록 새로운 유리 BackgroundEffect modifier를 사용하여 이전에 standard window에서 사용했던 것과 동일한 아름다운 유리 효과를 제공한다.
이제 여기에 spin 효과를 주고 싶다.
y축에 rotation 효과를 추가해준다.
회전을 tracking하기 위해 state 변수를 추가한다.

추가로 탭 했을 때 효과도 추가한다.

scale, offset, custom 3D transform을 포함한 3D 기능들을 사용할 수 있지만 더 좋은 방법을 해볼 수 있을 것이다.
바로 RealityView를 통해서.
RealityView는 RealityKit의 full power를 쉽게 사용할 수 있는 새로운 SwiftUI view이다.
RealityView에서는 RealityKit content를 불러오거나 만들수 있는 closure가 제공된다.
RealityView closure 안에서는 async-await를 바로 쓸 수 있고, 3DModel처럼 자동적으로 콘텐츠를 불러올 때 placeholder를 보여준다.
지구에 빛을 추가해주고 싶어서 image-based lighting에 대해 이미 작성해놓은 RealityKit code를 추가해준다.

더 많은 것을 알고 싶다면 이 비디오를 보시오.
RealityView에서 SwiftUI의 gestures는 자동적으로 동작한다.
지구에 mark를 추가하기 위한 tap gesture를 추가해보자.
이를 위해 SpatialTapGesture를 활용하여 tap한 지점의 3D location 값을 얻는다.

지구 entity에서 어딜 탭한건지 식별하기 위해 targetedToAnyEntity gesture modifier를 활용한다. 이 Modifier를 통해 tap한 entity에 대한 상대적인 위치 등 필요한 정보를 얻을 수 있다.
지구에 핀을 그리기 위해서는 RealityView attachments를 사용할 수 있다.
attachment는 custom SwiftUI view와 RealityKit entity를 혼합하기에 적합하다.
여러 SwiftUI view들을 attachments closure안에 추가할 수 있으며 이 뷰를 RealityKit entity로써 RealityView 어디든 배치할 수 있게 된다.

식별하기 위해 "pin" 태그를 붙인다.
그리고 RealityView에 추가해서 탭한 곳에 위치시킨다.
더 많은 것을 보고 싶다면...!
Full Space에서는 environment 어디든 콘텐츠를 배치할 수 있게된다.
사용자는 환경 내 어느 곳에나 컨텐츠를 배치하여 사용자의 환경을 창의적이고 새로운 방식으로 확장할 수 있게된다.
또는 주변을 숨김으로써 사람들을 완전히 몰입시켜 놀라운 새로운 경험을 만들어 낼 수도 있다.
Full Space를 앱에 추가하기 위해서는 WindowGroups에 했던 것처럼 단순히 새로운 ImmersiveSpace scene을 추가하면 된다.

이 바디 안에서 space content를 위한 root view를 추가해주고, space에 대해 ID를 제공해서 main window에서 개발적으로 space를 열 수 있게 한다.
Space를 열기 위해서 새로운 openImmersiveSpace environment action을 사용한다.
버튼에서 이 액션을 id 값과 함께 호출해준다.
그럼 버튼을 누르면 이렇게 창이 없어진다.

근데 아직 space에 완전히 몰입이 불가하다 -> immersion style을 적용해보겠다.
Full Space에는 여러 종류의 immersion style이 존재하고, 이 스타일들 사이에 전환도 가능하다.
space content가 실 세상과 함께 존재한다.
완전한 몰입을 제공하고 사용자 주변을 숨김으로써 그들을 새롭고 놀라운 세상으로 이동시킬 수 있다.
그리고 Progressive immersion은 사람들의 현실 세계 주변부에 기반을 둔 경험들을 위한 훌륭한 중간 지대이다.
Progressive Immersion에서 사람들은 몰입 정도를 조정하기 위해 Digital Crown도 사용할 수 있다.

이번에는 Full을 사용하겠다.
그러기 위해선 이러한 작업이 필요하다.
여기에는 지원하는 스타일의 리스트와 현재 선택을 제공하여 스타일 간 전환을 돕는다.
full immersion을 쓰면 시스템은 자동적으로 주변 실세계를 숨긴다. 사람들의 몰입을 위해 가상의 environment를 제공해줘야한다.
환경으로 star field를 추가해준다.
그리고 이를 SoloarSystem의 body에 추가해준다.
공간을 다음 단계로 발전시키기 위해서는 ARKit을 활용할 수 있다.
ARKit의 worldtracking, scene understanding 등의 API를 통해 실세상의 표면에 물체를 위치시킬 수 있게 된다.
그리고 hand tracking은 custom hand gesture를 만들 수 있는 엄청난 기술이다.
더 알고 싶다면 이 영상을 시청해라.
ARKit을 통합하면 새로운 hand gesture를 통해 손바닥으로 지구본을 움직일 수도 있다.

Full Space에 대해 더 알고 싶다면 이 영상을 보도록.
콘텐츠 렌더링에 대해서 full control 하고 싶다면 메탈을 활용해야하고 이 비디오를 보도록.
그 외에 보면 좋은 영상들.
