Apple 플랫폼 매트릭스: 어떤 타깃이 어떤 앱에 어울리는가
Apple은 개발자가 단일 Swift 코드베이스로 타깃팅할 수 있는 6개의 소비자용 컴퓨팅 플랫폼을 출시합니다. iPhone, iPad, Mac, Watch, Vision, TV가 그것입니다. SwiftUI와 iOS 26 툴체인은 이들 중 어느 것이든 추가하는 작업을 Xcode에서 체크박스를 클릭하는 수준의 일로 만들어 놓았습니다. 바로 그 체크박스가 함정입니다. 추가되는 모든 타깃은 기능이 아니라 책임입니다. 각각이 디자인, 테스트, 접근성, 런타임 모델, 그리고 지속적인 유지보수의 표면적을 확장합니다. 앱에 적합한 타깃 수는 프레임워크가 허용하는 것보다 적습니다.
이 클러스터의 앱들은 서로 다른 조합으로 출시됩니다. Return은 6개 플랫폼(iPhone, iPad, Mac, Watch, Vision, TV)에 출시되었습니다. Get Bananas는 4개 플랫폼(iPhone, iPad, Mac, Watch)에 출시되었습니다. Reps와 Water는 출시 전 단계로, 컴파일된 여러 타깃을 가지고 있지만 출시 전에 범위가 좁아질 예정입니다. Ace Citizenship과 Tappy Color는 각각 iPhone에만 출시됩니다. 같은 개발자, 같은 툴체인이지만 6개의 서로 다른 플랫폼 결정이 존재합니다. 이 결정들은 규칙을 따르며, 그 규칙은 공유된 지도를 가질 자격이 있습니다.
각 플랫폼은 “컴파일된다”가 아니라, 진정으로 추가되는 구체적인 사용자 가치를 통해 포함될 자격을 얻습니다. 출시까지 살아남는 매트릭스는 각 타깃이 스스로를 정당화하거나 잘려나간 후에 남는 것입니다.
TL;DR
- 6개 플랫폼, 6개의 서로 다른 책임: iPhone(기본), iPad(사이즈 클래스 적응), Mac(윈도우/메뉴/키보드 관용구), Watch(런타임 계약), Vision(공간 멘탈 모델), TV(포커스 엔진).
- 추가되는 각 타깃은 테스트 표면, 디자인 작업, 접근성, 그리고 지속적인 릴리스 조정 비용을 더합니다. Xcode의 “플랫폼 추가” 체크박스는 그 비용을 숨깁니다.
- 올바른 테스트는 기술적 테스트가 아니라 사용자 가치 테스트입니다. 사용자가 그 플랫폼에서 이 앱을 실행함으로써 진정으로 이익을 얻는가? 답이 “거기서도 작동합니다”라면 잘라내십시오.
- 대부분의 앱은 1~3개의 플랫폼에 출시되어야 합니다. 4~6개는 드문 경우이며, 다른 플랫폼이 제공할 수 없는 사용자 가치를 모든 플랫폼이 진정으로 추가할 때만 자격을 얻습니다.
iPhone은 기본값입니다
모든 Apple 앱은 iPhone에서 시작하거나 시작하지 않습니다. iPhone은 가장 큰 설치 기반, 가장 정교한 접근성 표면, App Store를 통한 가장 강력한 배포 경로, 그리고 정통적인 SwiftUI 디자인 언어를 가지고 있습니다. 제가 출시한 모든 클러스터 앱은 iPhone에서 실행됩니다. iPhone-first가 아닌 디자인으로 출시한 앱은 없습니다.
iPhone에 대한 사용자 가치 테스트는 다음과 같습니다. 사용자가 이 앱을 휴대폰에서 열어볼까요? 거의 모든 소비자 카테고리에서 답은 ‘예’입니다. 건강 및 피트니스 앱은 휴대폰에 거주합니다. 생산성 도구도 휴대폰에 거주합니다. 게임도 휴대폰에 거주합니다. 커뮤니케이션 도구도 휴대폰에 거주합니다. 기본값이 iPhone인 이유는 휴대폰이 사용자가 있는 곳이기 때문입니다.
예외는 개발 도구(Xcode, Terminal)와 작업 공간이 필요한 창작 도구(Final Cut, Logic)입니다. 이런 도구들은 Mac에서 시작하며, 명확한 핸드오프가 있을 때만 iPhone 컴패니언 자격을 얻습니다(운동 중 Watch의 심박수를 휴대폰이 차트로 보여주는 경우, Camera Continuity 등). 소비자 소프트웨어의 경우 iPhone-first는 논쟁의 여지가 없습니다.
iPad는 픽셀이 더 많은 iPhone이 아닙니다
유니버설 바이너리와 사이즈 클래스 덕분에 사이즈 클래스 브레이크포인트로 UIKit iPhone 앱을 iPad에 출시하는 것이 가능해졌습니다. SwiftUI는 @Environment(\.horizontalSizeClass)와 NavigationSplitView를 통해 같은 일을 더 쉽게 만들었습니다.1 “iPad에 출시”하는 기술적 비용은 낮습니다. 제품 비용은 그 앱이 정말로 iPad의 더 큰 캔버스를 누릴 자격이 있는가의 문제입니다.
iPad에 출시할 만한 신호 세 가지입니다.
앱이 사용자가 더 큰 화면에서 보고 싶어 하는 콘텐츠를 읽거나 만든다. 읽기 앱(책, 뉴스, 만화, 긴 문서). 그림/페인팅 앱(Procreate). Apple Pencil로 메모하기(Notability, GoodNotes). Get Bananas가 iPad 슬롯을 얻는 이유는 섹션이 있는 쇼핑 목록이 좁은 캔버스보다 넓은 캔버스에서 더 유용하기 때문입니다. iPad 디자인은 동일한 섹션 목록을 더 큰 영역에 맞게 적응시킵니다.
앱이 iPhone 또는 Mac과 핸드오프 가치를 가진다. Apple Notes, Reminders, Mail은 모두 사용자가 연속성을 기대하기 때문에 iPad 슬롯을 얻습니다. iPad에서의 Return의 명상 기록도 같은 이유로 슬롯을 얻습니다. 사용자는 iPhone에서 시작해서 타이머가 실행되는 동안 iPad를 흘끗 봅니다.
앱이 iPad 네이티브 입력 어포던스를 가진다. 스케치/필기를 위한 Apple Pencil. 더 큰 표면에서의 멀티핑거 제스처. 타일 기반 레이아웃이 도움이 되는 Stage Manager 워크플로. 어포던스가 iPhone에 존재하지 않는다면, iPad 타깃은 자기 자리를 얻습니다.
iPad에 출시하지 말아야 할 신호입니다.
규모가 커져도 추가 가치가 없는 단일 칼럼 콘텐츠. 명상 타이머의 기본 뷰는 카운트와 버튼입니다. iPad는 둘 다 더 크게 만들지만, 그것은 기능이 아닙니다. 빠른 수분 섭취 로깅 트래커도 마찬가지입니다. 더 넓은 화면은 5초간의 로깅 세션 동안 사용자가 하는 일을 바꾸지 않습니다.
iPhone 전용 하드웨어에 의존하는 앱(Dynamic Island, 특정 Pro 전용 카메라 포맷, iPhone 형태의 그립 인체공학). 이런 디자인 가정은 잘 변환되지 않습니다. 디자인을 다시 만들거나 타깃을 건너뛰십시오.
사용자가 이미 Mac에 더 좋은 목적지를 가지고 있는 앱. 키보드 지원이 없는 iPad의 코드 에디터는 Mac 앱의 불완전한 버전입니다. iPad의 특정 입력 모델에서 디자인이 자기 자리를 얻지 못한다면 타깃을 건너뛰십시오.
Mac은 윈도우, 메뉴 바, 키보드 관용구입니다
네이티브 macOS 타깃이나 “Designed for iPad”(Mac Catalyst는 UIKit 코드를 Mac으로 가져오는 UIKit 등가 경로입니다)를 통해 Mac에 출시된 SwiftUI 앱은 macOS에서 실행되지만 진짜 Mac 앱을 만들어내지는 못합니다.2 진짜 Mac 앱은 윈도우 리사이징 시맨틱, 메뉴 바(SwiftUI의 CommandMenu와 CommandGroup 빌더가 있는 .commands { } Scene 모디파이어), 키보드 단축키, macOS 파일 선택기, Finder와의 드래그 앤 드롭, 그리고 Mac 네이티브 공유 기능을 존중합니다.3 이들 중 어느 것이라도 건너뛰면 iPad 앱이 윈도우에 갇혀 있는 듯한 경험이 만들어지고, Mac 사용자들은 그것을 알아채고 평가합니다.
Mac에 출시할 만한 신호입니다.
사용자가 앱에서 시간을 보내며 진짜 데스크톱 윈도우가 도움이 된다. Mac에서의 Get Bananas가 슬롯을 얻는 이유는 책상에서 긴 쇼핑 목록을 편집하는 사용자에게 키보드 내비게이션이 가능한 진짜 윈도우가 도움이 되기 때문입니다. Mac에서의 Return이 슬롯을 얻는 이유는 작업 머신에서 명상 타이머를 실행하고 싶어 하는 사용자에게 진짜 메뉴바 앱이나 특정 모서리에 고정된 윈도우가 도움이 되기 때문입니다.
다중 윈도우 또는 다중 문서 워크플로. 분할 패널이 있는 코드 에디터. 참고 이미지를 나란히 놓는 사진 편집기. 스프레드시트. 이들 중 어느 것도 iPad나 iPhone에서 적절한 형태로 살아남지 못합니다. Mac이 올바른 플랫폼입니다.
키보드 중심의 상호작용. 키보드를 무시하는 Mac의 SwiftUI 앱은 이름뿐인 Mac 앱입니다. 새로 만들기는 Cmd+N, 닫기는 Cmd+W, 포커스 이동은 Tab, 선택은 화살표 키. 비용은 앱마다 발생합니다. 모든 Mac 타깃은 잘 고려된 키보드 표면이 필요합니다.
Mac에 출시하지 말아야 할 신호입니다.
앱이 윈도우의 도움을 받지 않는 작은 단일 작업 도구. 사용자가 하루에 한 번 5분 동안 실행하는 아침 타이머는 Mac 타깃이 필요하지 않습니다. 사용자는 Mac 옆에 있는 iPhone에서 그것을 실행할 수 있습니다.
iPhone 형태의 UI가 근본적으로 변환되지 않는 앱. 카메라 앱. Apple Watch 컴패니언 앱. 입력 모델이 터치 우선이고 키보드/마우스 등가물이 휴대폰을 만지는 것보다 더 나쁠 앱.
팀이 지속적인 Mac 전용 유지보수를 약속할 수 없다. Mac 릴리스는 iPhone 릴리스와 다르게 검토됩니다. macOS 업데이트 사이클, Gatekeeper용 서명, 공증, Mac에 특화된 App Store 심사. 이 각각은 팀이 예산을 잡아야 하는 릴리스 사이클 작업을 추가합니다. 팀이 예산을 잡지 않을 거라면 타깃을 건너뛰십시오.
Apple Watch는 런타임 계약입니다
Watch는 “여기에 출시하세요”가 적극적으로 오해를 부르는 지시인 플랫폼입니다. watchOS Runtime Is a Contract, Not a Background Task에서 자세히 다룬 Watch의 런타임 모델은 iOS와 근본적으로 다릅니다. 손목이 내려가면 시스템이 앱을 일시 중단하고, 특정 세션 타입(WKExtendedRuntimeSession의 self-care, mindfulness, physical-therapy, alarm, 그리고 HKWorkoutSession의 workout-processing과 다이빙 세션의 underwater-depth)만이 일시 중단 후에 실행될 수 있습니다.4 런타임 스토리가 없는 Watch 타깃은 두 번째 사용에서 망가집니다.
Watch에 출시할 만한 신호입니다.
앱이 watchOS 런타임 모델이 인식하는 세션 형태를 가진다. 명상 타이머(mindfulness 세션). 피트니스 앱(workout-processing 백그라운드 모드의 HKWorkoutSession). 스마트 알람(alarm). 물리치료 및 셀프케어 앱(매칭되는 세션 타입). Return이 Watch에 출시되는 이유는 명상이 mindfulness에 깔끔하게 매핑되기 때문입니다. Watch 앱은 런타임 계약이 허용하기 때문에 손목이 내려가도 타이머를 계속 실행합니다.
사용자가 손목을 입력 표면으로 진정으로 원한다. 운동 중 심박수 뷰어. 휴대폰을 꺼내지 않고 시작하는 타이머. 한 번의 시선으로 정보를 표시하는 컴플리케이션. Get Bananas는 iPhone 정전 매장과 페어링된 빠른 목록 확인 표면으로 Watch에 출시됩니다. Reps 같은 운동 앱은 같은 이유로 Watch 타깃을 얻습니다. 손목에서 세트를 로깅하는 것이 주머니에서 휴대폰을 꺼내는 것보다 빠르기 때문입니다.
컴패니언 앱 가치가 진짜다. 일부 Watch 앱은 주로 iPhone 주도 데이터의 디스플레이로 존재합니다(예: iPhone이 타이머를 실행하고 Watch가 남은 카운트를 표시하는 레시피 타이머). 그런 앱들이 슬롯을 얻으려면 크로스 디바이스 동기화가 정직하게 구축되어야 하고(Single Source of Truth: SwiftData + MCP + iCloud에서 다룸), Watch 뷰가 단순한 미러링을 넘어선 실제 작업을 수행해야 합니다.
Watch에 출시하지 말아야 할 신호입니다.
앱이 주장할 수 있는 세션 타입이 없다. Watch의 읽기 앱은 이름뿐인 Watch 앱입니다. 사용자는 손목으로 책을 읽을 수 없습니다. 런타임 모델이 세션을 연장하지 않습니다. 건너뛰십시오.
팀이 watchOS 전용 디버깅을 약속할 수 없다. Watch 디버깅은 독특하게 고통스럽습니다. 시뮬레이터 동작이 실제 Apple Watch에서 손목 내림 조건에서만 드러나는 방식으로 실제 디바이스 동작과 갈라집니다. 팀이 하드웨어와 거기서 테스트할 의지가 없다면, Watch 타깃은 망가진 채로 출시됩니다.
데이터 모델이 크로스 디바이스 동기화 봉투에 맞지 않는다. iPhone에서 Watch로의 크로스 디바이스 동기화는 일반적으로 라이브 상태에는 WatchConnectivity, 작은 영구 상태에는 NSUbiquitousKeyValueStore를 사용합니다(Return은 후자를 세션 기록 동기화에 사용합니다. 멀티 플랫폼 출시 포스트에서 다룸). 스토어는 모든 키에 걸쳐 1MB 캡과 1024개 키 최대치를 가집니다.5 앱의 세션 상태가 그 봉투에 들어갈 수 없다면, Watch 타깃에는 다른 동기화 아키텍처가 필요하며, 그것은 진짜 엔지니어링 투자입니다.
Vision은 공간 멘탈 모델입니다
Vision Pro는 앱들이 3D 공간에 떠 있는 평면 패널로 출시되도록 유혹합니다. 그 패널은 SwiftUI 윈도우이며, visionOS의 SwiftUI는 그것을 출시하는 일을 원클릭 작업으로 만듭니다. 그 패널은 더 나쁜 iPad입니다. 플랫폼의 진정한 가치는 RealityKit and the Spatial Mental Model에서 다룬 공간 멘탈 모델에서 옵니다. 거기서 콘텐츠는 패널 안이 아니라 방 안에 거주합니다.
Vision에 출시할 만한 신호입니다.
앱이 방 안에 있는 것이 도움이 되는 3D 콘텐츠를 가진다. 사용자가 걸어 다닐 수 있는 가상 조각. 실제 벽에 놓는 줄자. 사용자 신체의 거울 이미지에 자세 큐를 투사하는 운동 코치. visionOS에 나타나는 대부분의 클러스터 앱들은 네이티브 visionOS 타깃이 아니라 “Designed for iPad” 호환성을 통해 그렇게 합니다. 그 호환성은 사용자에게 괜찮지만, 앱을 Vision 네이티브 경험으로 만들지는 않습니다. RealityKit의 공간 멘탈 모델에 관한 포스트는 플랫폼을 누리는 자격을 얻는 것이 단순히 거기서 실행되는 것 이상을 의미한다고 주장합니다.
핸드 트래킹이 올바른 입력 모델이다. 핀치하여 잡기, 두 손으로 스케일링, 공중에서 그리기. visionOS는 다른 어떤 플랫폼에도 없는 입력 어포던스를 제공합니다. visionOS 슬롯을 얻는 앱들은 그것에 기댑니다.
앱이 공간 전용 표면(잠금 화면 등가물, 몰입형 공간, 장식)을 다룬다. Vision에서 iPhone UI를 떠다니게만 하는 생산성 앱은 디바이스를 사용한 첫날에 사용자에게 시각적 소음입니다. 사용자가 계속 돌아오게 만드는 앱은 공간 표면을 활용하는 앱입니다.
Vision에 출시하지 말아야 할 신호입니다.
앱이 근본적으로 패널 모양이며 깊이의 도움을 전혀 받지 않는다. 메모 앱, 채팅 앱, 설정 유틸리티. visionOS는 그것들을 실행하지만, 사용자는 iPad 대신 visionOS에서 그것들을 사용할 이유가 없습니다. 건너뛰십시오.
개발 팀이 visionOS 전용 테스트를 가지고 있지 않다. visionOS는 가장 작은 설치 기반과 가장 취약한 패턴을 가진 플랫폼입니다. 실제 디바이스 없이 Vision 타깃을 테스트하는 것은 watchOS 사례보다도 독특하게 어렵습니다.
프라이버시와 존재감 우려가 지배적이다. 건강 정보 공개 앱. 민감한 직장 도구. visionOS 디바이스는 iPhone과는 다른 방식으로 가족 구성원 간에 공유됩니다. 비공개 정보를 표면화하는 앱은 거기서 iPhone과는 다른 자세를 취해야 합니다.
Apple TV는 포커스 엔진입니다
TV 앱은 Siri Remote의 포커스 엔진에 의해 구동됩니다. 사용자는 리모컨으로 포커스 하이라이트를 이동시키고, 눌러서 선택하며, 터치 상호작용을 절대 보지 않습니다. tvOS의 SwiftUI는 .focusable(...) 모디파이어, @FocusState 프로퍼티 래퍼, 상태 바인딩을 위한 .focused(...)를 통해 이를 지원하지만, 모든 TV 앱은 처음부터 포커스 디자인이 필요합니다.6 iPhone의 탭 앤 스크롤 모델은 변환되지 않습니다.
TV에 출시할 만한 신호입니다.
앱이 TV 시청 거리에서의 콘텐츠 소비용이다. 스트리밍 비디오(Apple TV+, Netflix). 사진 슬라이드쇼. 사용자가 리모컨으로 제어하는 가족용 게임 앱. 사용자는 소파에 있고, 화면은 멀리 있으며, 입력은 희박합니다. TV가 올바른 플랫폼입니다.
앱이 iPhone에 없는 “기대어 보기” 사용 사례를 가진다. 사용자가 따라 하는 운동 비디오. 화구 옆에서 사용자가 참조하는 요리 앱. 잠들면서 사용자가 듣는 잠자리 동화. 이들 중 어느 것도 커피 테이블에 세워둔 휴대폰으로는 잘 제공되지 않습니다.
상호작용 모델이 희박하고 포커스 중심의 내비게이션에 맞는다. 사용자가 한 번에 하나씩 고르는 항목 목록. 옵션 그리드. 선형 재생 흐름. 그보다 복잡한 어떤 것이든, 멀티터치 제스처, 세밀한 텍스트 입력, 드래그 앤 드롭은 tvOS에서 작동하지 않으며 타깃이 잘못되었음을 의미합니다.
TV에 출시하지 말아야 할 신호입니다.
앱이 텍스트 입력을 필요로 한다. 리모컨을 통한 TV 텍스트 입력은 모든 Apple 플랫폼 중 최악의 입력 모델 중 하나입니다. 앱이 검색창 이상의 어떤 것을 필요로 한다면, TV를 건너뛰십시오.
앱의 가치가 다른 작업을 위해 사용자의 손이 자유로운 것에 의존한다. 피트니스 추적. 건강 모니터링. 실시간 협업. TV는 화면이지 웨어러블이 아닙니다.
유지보수 비용이 설치 기반에 비해 너무 높다. tvOS는 iOS에 비해 작은 설치 기반을 가지고 있습니다. 개발 비용은 진짜입니다(포커스 디자인, 별도의 테스트, tvOS용 App Store 심사). 대부분의 앱에서 수학은 슬롯을 정당화하지 않습니다. 명상 앱이 Apple TV 슬롯을 얻는 것은 사용 사례가 실제로 보상하는 진짜 “내가 소파에 앉아 있는 동안 낮은 밝기로 화면에 두기” 모드가 있을 때만입니다. 그 모드 없이는 타이머가 TV의 기대어 보기 패턴에 깔끔하게 매핑되는 앱이라도 유지보수 비용을 누릴 자격이 없습니다.
실제의 매트릭스
각 클러스터 앱의 실제 매트릭스입니다.
| 앱 | 상태 | 타깃 | 각 슬롯의 이유 |
|---|---|---|---|
| Return (명상) | 출시됨 | iPhone, iPad, Mac, Watch, Vision, TV | Watch에서의 mindfulness 세션. 책상 컴패니언으로서의 iPad와 Mac. 몰입형 모드를 위한 visionOS. 소파 모드 기대어 보기를 위한 TV. 6개 플랫폼인 이유는 각 플랫폼이 자격을 얻기 때문일 뿐. |
| Get Bananas (쇼핑) | 출시됨 | iPhone, iPad, Mac, Watch | 책상 편집을 위한 iPad와 Mac. iPhone 정전 매장과 페어링된 손목 위 빠른 목록 확인용 Watch. |
| Reps (운동) | 출시 전 | iPhone, iPad, Mac, Vision, Watch (컴파일됨) | 손목 입력은 세트 로깅을 위한 가치 명제. 더 큰 표면들은 컴파일되지만 출시 전에 출시 타깃 범위가 좁아질 가능성이 큼. |
| Water (수분 섭취) | 출시 전 | iPhone, iPad, Mac, Vision (컴파일됨) | 빠른 로깅은 규모에서 명백한 이점이 없음. 출시 타깃은 iPhone-first로 좁아질 것. |
| Ace Citizenship (학습 도구) | 출시됨 | iPhone | 학습 세션은 휴대폰 모양. iPad와 Mac 타깃은 사용자 가치가 진짜가 될 때까지 미뤄짐. |
| Tappy Color (어린이 색칠 게임) | 출시됨 | iPhone | 탭 타깃 게임. 손목이나 리모컨으로 변환되지 않음. |
패턴은 다음과 같습니다. 각 행은 의도적인 추가만큼이나 의도적인 절단입니다. Return이 6개 플랫폼에 도달하는 이유는 각 플랫폼이 특정 사용자 가치 테스트를 통해 정당화되기 때문입니다. iPhone 전용 앱들이 거기에 머무는 이유는 다른 어떤 것도 그렇지 않기 때문입니다. 같은 툴체인, 다른 제품, 다른 매트릭스.
매트릭스를 지속 가능하게 만드는 세 가지 아키텍처 결정
다중 플랫폼 앱이 자체 무게에 무너지지 않게 하는 세 가지 패턴입니다.
공유 코어는 #if os(iOS), #if os(macOS), #if os(watchOS)(그리고 동료들)을 사용하여 플랫폼 전용 표면을 게이트합니다.7 핵심 도메인 로직(데이터 모델, 비즈니스 규칙, 동기화)은 모든 곳에서 컴파일됩니다. 플랫폼 전용 UI는 컴파일 타임 조건문 뒤에 거주합니다. SwiftUI의 @available(iOS 26.0, macOS 26.0, ...)는 OS 버전 차이를 다룹니다. 플랫폼 간에 진정으로 갈라지는 표면(iPhone 등가물이 없는 Mac 메뉴 바, iPad 등가물이 없는 Watch 컴플리케이션)은 #if os(...) 게이트 뒤에 있는 타깃 전용 그룹의 자체 파일을 가집니다.
크로스 디바이스 동기화는 도메인별로 선택된 하나의 기반을 통과합니다. 디바이스 간 작은 세션 수준 상태에는 NSUbiquitousKeyValueStore(Return은 이를 크로스 디바이스 타이머 상태에 사용). 크로스 프로세스 브리지에는 iCloud Drive JSON 파일(Get Bananas는 Single Source of Truth에서 다룬 MCP 서버와 함께 이를 사용). 인프로세스 상태에는 SwiftData. 도메인별로 기반을 혼합하는 것은 괜찮습니다. 같은 도메인에 두 개의 기반을 사용하는 것이 드리프트를 만들어내는 실패 모드입니다.
각 플랫폼은 앱별로 문서화된 명시적인 거부 패턴을 가집니다. “사용 사례에 기대어 보기 모드가 없는 한 우리는 TV에 출시하지 않을 것이다.” “앱이 패널이 아니라 RealityKit을 사용하는 한 우리는 Vision에 출시하지 않을 것이다.” “세션 타입 없이 우리는 Watch에 출시하지 않을 것이다.” 거부는 What I Refuse To Write About의 정신으로 앱별로 포착되어 일관되게 적용되는 프로젝트 결정입니다.
플랫폼을 추가하는 것이 잘못된 때
쉬운 길이 잘못된 길인 세 가지 경우입니다.
팀이 툴체인이 쉽게 만들어 주기 때문에 타깃을 추가합니다. Xcode의 “타깃 복제” 마법사는 Mac 또는 visionOS 타깃을 추가하는 것을 4번의 클릭 작업으로 만듭니다. 그 4번의 클릭에는 디자인 검토, 접근성 감사, App Store 스크린샷 제작, 지속적인 릴리스 조정, 또는 플랫폼별 테스트가 포함되지 않습니다. 그런 작업 없이 마법사에서 출시된 타깃은 첫날부터 망가져 있습니다.
팀이 타깃 수를 상태 신호로 다룹니다. “우리는 5개 Apple 플랫폼에 출시합니다”는 출시 트윗에서 인상적으로 들립니다. 출시 트윗은 사용자 디바이스에서 실행되지 않습니다. 앱이 실행됩니다. 두 플랫폼을 완벽하게 처리하는 2 플랫폼 앱이 늘어진 5 플랫폼 앱보다 더 나은 제품입니다.
팀이 지속적인 유지보수를 과소평가합니다. 각 Apple 플랫폼은 매년 주요 OS 업데이트를 출시합니다. 5 플랫폼 앱은 반응해야 할 5세트의 릴리스 노트, 테스트해야 할 5세트의 동작 변경, 최신 상태로 유지해야 할 5세트의 App Store 메타데이터를 가집니다. 비용은 복리로 누적됩니다. 유지할 대역폭 없이 5개 모두에 출시하는 팀은 그 플랫폼 중 3개에서 천천히 부패하는 제품을 만들어냅니다.
이 패턴이 iOS 26+에 출시되는 앱에 의미하는 것
세 가지 시사점입니다.
-
플랫폼 포함은 엔지니어링 결정 이전에 제품 결정입니다. Xcode 체크박스는 엔지니어링 측면이고, 사용자 가치 테스트는 제품 측면입니다. “사용자가 그 플랫폼에서 이 앱을 실행함으로써 진정으로 이익을 얻는가”에 대한 명확한 답이 없다면, 타깃은 잘립니다.
-
각 플랫폼은 특정 책임을 가져옵니다. 사이즈 클래스(iPad), 윈도우/메뉴/키보드(Mac), 런타임 계약(Watch), 공간 모델(Vision), 포커스 엔진(TV). 책임을 건너뛰면 Mac에 있는 iPad 앱, Vision에 있는 휴대폰 앱, Watch에 있는 iPhone 앱이 만들어지며, 모두 그 플랫폼의 실제 사용자가 알아채는 가시적인 실패입니다.
-
대부분의 앱은 1~3개의 플랫폼에 출시되어야 합니다. 4~6개는 드물며 각 플랫폼이 진정으로 사용자 가치를 추가할 때만 자격을 얻습니다. 클러스터의 앱들은 1개에서 6개에 걸쳐 있습니다. 6 플랫폼 사례(Return)는 드문 종점이며, 거기서 추가된 모든 플랫폼은 자체 사용자 가치 테스트가 있는 별도의 제품 결정이었습니다.
전체 Apple 생태계 클러스터입니다. Apple Intelligence 표면을 위한 타입드 App Intents; 에이전트 표면을 위한 MCP 서버; 그들 사이의 라우팅 질문; 인앱 온디바이스 LLM 기능을 위한 Foundation Models; 런타임 vs 툴링 LLM 구분; 세 가지 표면 종합; 단일 진실 공급원 패턴; Xcode 통합을 위한 Two MCP Servers; Apple 개발을 위한 훅; Live Activities; watchOS 런타임 계약; SwiftUI 내부; RealityKit의 공간 멘탈 모델; SwiftData 스키마 규율; Liquid Glass 패턴; 멀티 플랫폼 출시; 내가 글쓰기를 거부하는 것. 허브는 Apple Ecosystem Series에 있습니다. 더 넓은 iOS-AI-에이전트 컨텍스트는 iOS Agent Development guide를 참조하세요.
FAQ
Apple 플랫폼 타깃을 추가할지 어떻게 결정하나요?
툴체인이 허용하는지가 아니라 사용자가 그 플랫폼에서 앱을 실행함으로써 진정으로 이익을 얻는지 물어보세요. Xcode 체크박스는 기술적 측면이고, 사용자 가치 테스트는 제품 측면입니다. 각 플랫폼은 특정 책임(사이즈 클래스, 윈도우/메뉴, 런타임 계약, 공간 모델, 포커스 엔진)과 특정 유지보수 비용을 가져옵니다. 답이 “거기서도 작동합니다”라면, 올바른 결정은 보통 타깃을 건너뛰는 것입니다.
6개의 모든 Apple 플랫폼에 출시해야 하나요?
보통 아닙니다. 대부분의 앱은 1~3개의 플랫폼에서 이익을 얻습니다. 4~6개는 드물며 각 플랫폼이 진정으로 사용자 가치를 추가할 때만 자격을 얻습니다(Return이 6개 모두에 도달하는 이유는 mindfulness 세션이 Watch에 맞고, 타이머가 책상 컴패니언으로서 iPad와 Mac에 맞으며, visionOS가 몰입형 모드에 맞고, TV가 기대어 보기 소파 사용 사례에 맞기 때문). 대부분의 앱에서 tvOS의 상호작용 모델과 visionOS의 공간 요구 사항은 맞지 않으며, 올바른 결정은 그 타깃들을 건너뛰는 것입니다.
iPad 타깃을 추가할 때 가장 흔한 실수는 무엇인가요?
iPad를 “픽셀이 더 많은 iPhone”으로 다루는 것입니다. 사이즈 클래스 적응 없이 iPad에 떨어뜨린 SwiftUI iPhone 앱은 iPad 사용자가 즉시 절반의 노력으로 판단하는 늘어진 단일 칼럼 UI를 만듭니다. 올바른 패턴은 @Environment(\.horizontalSizeClass)를 읽고, 더 큰 캔버스에 맞게 레이아웃을 적응시키며(NavigationSplitView를 통해 두 칼럼이 적절한 곳, 그렇지 않으면 편안한 간격의 단일 목록), Apple Pencil과 멀티핑거 어포던스를 iPad 전용 가치로 고려하는 것입니다.
왜 Apple Watch는 다른 플랫폼들과 그렇게 다른가요?
watchOS는 iOS의 백그라운드 실행 모델을 가지고 있지 않습니다. 손목이 내려가면 시스템이 앱을 일시 중단하고, 특정 세션 타입(WKExtendedRuntimeSession의 self-care, mindfulness, physical-therapy, alarm, 그리고 HKWorkoutSession의 workout-processing)만이 일시 중단 후에 실행될 수 있습니다.4 깔끔한 세션 타입이 없는 앱은 두 번째 사용에서 망가지는 경험을 만들어냅니다. 클러스터의 watchOS 런타임 포스트가 계약을 자세히 다룹니다.
플랫폼 매트릭스 전반에 걸쳐 크로스 디바이스 동기화는 어떻게 작동하나요?
세 가지 기반이 있습니다. 작은 키-값 상태(설정, 마지막 선택 탭, 크로스 디바이스 타이머 상태)에는 NSUbiquitousKeyValueStore,5 크로스 프로세스 브리지에는 iCloud Drive 파일(Get Bananas + MCP 서버 패턴), 인프로세스 상태에는 SwiftData. 도메인별로 하나의 기반을 선택하세요. 같은 도메인에 두 개를 혼합하면 드리프트가 발생합니다. 클러스터의 단일 진실 공급원 포스트가 결정 매트릭스를 설명합니다.
참고 자료
-
Apple Developer, “Adopting size classes” and “NavigationSplitView”. iPhone과 iPad 전반에 걸친 적응형 레이아웃을 위한 사이즈 클래스와 SwiftUI의 분할 뷰 컨테이너. 2026-05-05 검색. ↩
-
Apple Developer, “Mac Catalyst”. UIKit 코드를 Mac으로 가져오는 경로. SwiftUI Mac 앱은 SwiftUI 라이프사이클을 통해 macOS에서 네이티브로 실행됩니다. “Designed for iPad”는 Apple Silicon Mac에서 iPad 바이너리를 수정 없이 실행하는 별도의 경로입니다. 2026-05-05 검색. ↩
-
Apple Developer, “Commands”, “CommandMenu”, “CommandGroup”.
Commands빌더가 있는.commands { }Scene 모디파이어는 SwiftUI Mac 앱이 메뉴 바 항목을 구성하는 방법입니다. 2026-05-05 검색. ↩ -
Apple Developer, “WKExtendedRuntimeSession”, “WKBackgroundModes”, “HKWorkoutSession”. Apple은 4가지
WKExtendedRuntimeSession타입(self-care, mindfulness, physical-therapy, alarm)을 문서화합니다. workout-processing과 underwater-depth는HKWorkoutSession과 다이빙 세션을 위한 별도의 백그라운드 모드입니다. 클러스터의 watchOS 런타임 포스트가 계약을 자세히 다룹니다. 2026-05-05 검색. ↩↩ -
Apple Developer, “NSUbiquitousKeyValueStore”. 모든 키에 걸쳐 1MB 총 캡, 1024개 키 최대치. 2026-05-05 검색. ↩↩
-
Apple Developer, “focusable(_:)”, “FocusState”, “focused(_:)”. tvOS 포커스 엔진 앱을 구동하는 SwiftUI 포커스 표면. 2026-05-05 검색. ↩
-
Apple Developer, “Conditional compilation”. Swift의
#if os(...)지시문은 컴파일 타임에 플랫폼 전용 코드를 게이트합니다. 2026-05-05 검색. ↩