← 모든 글

Xcode 27.1 beta: iPhone Duo 시뮬레이터 속의 내 앱

Xcode 27.1 beta(27A9269)는 2026년 9월 18일 금요일에 나왔고, 첫 iOS 27.1 SDK와 시뮬레이터용 iPhone Duo 디바이스 타입을 함께 담고 있습니다. Xcode 27.0이 나온 지 나흘 만입니다. SDK에는 Apple의 준비 가이드가 언급하는 iPhone Duo API가 모두 들어 있고, 디바이스 타입의 프로파일은 두 디스플레이를 3x 기준 1398 × 2034 픽셀과 2007 × 2853 픽셀, 곧 466 × 678 포인트와 669 × 951 포인트로 정의합니다. 시뮬레이터 런타임은 별도 다운로드이며 Xcode가 필요할 때 받아 옵니다. Apple 자신의 노트는 시뮬레이터가 아직 하지 못하는 일 세 가지를 적어 두었습니다. Device Hub의 세 포즈에서 프로브 앱을 돌려 보니, 접은 상태에서는 466 × 678 포인트 디스플레이에, 펼친 상태에서는 951 × 669 포인트 디스플레이에 올라갔고, 펼친 상태에서는 가로세로 모두 regular였으며, 어느 포즈에서도 예약 영역은 보고되지 않았고, 앱이 내부 디스플레이에 있는 동안에도 UIScreen.main은 여전히 외부 디스플레이 값을 답했습니다.12456 {.answer-block}

TL;DR

  • 날짜와 빌드. Apple의 Releases 피드는 Xcode 27.1 beta(27A9269)를 9월 18일 금요일 자로 올렸습니다. xcodebuild -versionXcode 27.1Build version 27A9269를 출력하고, iPhoneOS와 iPhoneSimulator SDK는 둘 다 iOS 27.1 빌드 24A94403이라고 밝힙니다. Swift 컴파일러의 버전 문자열 swiftlang-6.4.0.34.1도, 링커의 ld-27037.1도 Xcode 27.0과 같습니다. xip은 2,027,292,809바이트, 펼친 앱은 3.6 GiB이고, Xcode 27.0을 대체하지 않고 그 옆에 설치됩니다.14
  • Duo API는 SDK 안에 있습니다. 9월 17일 확인에서 27.0 SDK에 없던 열 개의 이름은 27.1 SDK에 모두 있습니다. SwiftUICore의 ArrangementViewreservedRegions(kind:options:layoutDirectionBehavior:), SwiftUI의 toolbarVerticalBehavior(_:), UIKit의 UIArrangementViewControllerpreferredVerticalBarBehavior, verticalBarEdge가 그 안에 있습니다. SwiftUI는 이들에 @available(anyAppleOS 27.1, *)를 붙였고, UIKit 헤더는 arrangement 컨트롤러와 예약 영역 메서드에 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1))를 붙였습니다. 문서 페이지가 적어 둔 것보다 플랫폼이 두 개 더 많습니다.4
  • 시뮬레이터 프로파일이 디스플레이 크기를 적어 두었습니다. iPhone Duo 디바이스 타입(iPhone19,4, 제품 클래스 V68, 모델 번호 A3447)은 내장 디스플레이 두 개를 정의합니다. primary는 1398 × 2034 픽셀에 스케일 3, primary-1은 2007 × 2853 픽셀에 스케일 3이고 네이티브 방향은 270도입니다. 3으로 나누면 466 × 678 포인트와 669 × 951 포인트이며, 내부 쪽 숫자는 제 Duo 개발자 글이 9월 10일에 App Store Connect 스크린샷 크기에서 추론한 바로 그 값입니다. 프로파일은 런타임 27.1 이상을 요구합니다.5
  • 실제 앱을 올리면 시뮬레이터가 어떻게 반응하는가. Device Hub에는 Closed(접은 상태), Book(반쯤 편 상태), Open(펼친 상태) 세 포즈와 Rotate Right(오른쪽으로 회전)가 있습니다. Closed에서 프로브는 외부 디스플레이를 받습니다. 466 × 678 포인트, 폭은 compact, split arrangement는 위아래로 쌓입니다. Open에서는 내부 디스플레이로 옮겨 갑니다. 가로가 네이티브인 951 × 669 포인트, size class는 가로세로 모두 regular, 세이프 에어리어 인셋은 좌우 각각 34, split arrangement는 나란히 배치됩니다. 회전시키면 폭 669, 높이 951 포인트가 되고 그래도 양쪽 모두 regular입니다. Book이 앱에 준 지오메트리는 Open과 같았습니다. 모든 포즈에서 reservedRegions는 비활성 영역을 포함해도 아무것도 반환하지 않았고, toolbarVerticalEdge는 nil에 머물렀으며, 툴바는 가로로 그려졌고, 앱이 내부 디스플레이에 있는 동안에도 UIScreen.main.bounds는 계속 466 × 678을 보고했습니다.6
  • 이 베타가 아직 하지 못하는 일. Apple의 노트는 이렇게 적습니다. “Initial Simulator launch can take several minutes.”(187708500), “StandBy is unavailable in the iPhone Duo Simulator runtime.”(187708663), “Running and debugging most app extensions is unavailable in the iPhone Duo Simulator runtime.”(187708767). 앱을 Mac에도 내놓는다면 Mac Catalyst Known Issues 두 건이 더 붙습니다. 그리고 Apple이 적지 않은 것이 하나 있습니다. 런타임 다운로드가 첫 시도에서 Download failed.로 실패했고, 다시 시도하니 성공했습니다.23

이 베타에는 무엇이 들어 있습니까?

Apple의 Releases 피드는 “Xcode 27.1 beta (27A9269)”를 9월 18일 금요일 오전 10시(PT)에, 같은 날 오후에는 “TestFlight Update”를 올렸습니다. 같은 날짜의 App Store Connect 릴리스 노트에는 “You can now submit apps built with Xcode 27.1 beta using the SDK for iOS 27.1 beta or iPadOS 27.1 beta for internal and external testing.”라고 적혀 있습니다.1 릴리스 노트의 Overview는 SDK 목록을 이렇게 지목합니다. “Xcode 27.1 beta includes Swift 6.4 and SDKs for iOS 27.1, iPadOS 27, tvOS 27, watchOS 27, macOS 27, and visionOS 27. Xcode 27.1 beta supports on-device debugging in iOS 17 and later, tvOS 17 and later, watchOS 10 and later, and visionOS. Xcode 27.1 beta requires a Mac running macOS Tahoe 26.6 or later.”2 이 목록은 적힌 그대로 읽으십시오. 27.1인 플랫폼은 iOS뿐이고, SDK 자신의 SDKSettings.plist도 버전 27.1이라고 보고합니다. 반면 App Store Connect는 같은 SDK를 “iPadOS 27.1 beta”라고 부르는데, 이 어긋남은 Xcode 27 글이 이어서 다루고 있습니다.

다운로드는 버전 번호에서 짐작하는 것보다 작습니다. xip은 2,027,292,809바이트이고, Apple의 Software Update 인증서로 서명되어 있으며, 펼치면 Xcode 27.0과 같은 크기인 3.6 GiB 앱이 됩니다. 명령줄 작업이라면 폴더로 xip --expand, /Applications/Xcode-27.1-beta.app으로 이름 변경, 그리고 그곳을 가리키는 DEVELOPER_DIR, 설치는 이것이 전부입니다. 그다음 베타 아래에서 처음 실행한 xcodebuild 호출은 함께 들어 있는 CoreTypes.pkgXcodeSystemResources.pkg를 스스로 설치하느라 2분쯤을 썼습니다. xcodebuild -runFirstLaunch가 명시적으로 수행하는 단계이며, 그중 두 번째 패키지가 바로 iPhone Duo 디바이스 타입을 제자리에 놓아 주는 주인공입니다.4 앱이 담고 있지 않은 것은 시뮬레이터 런타임입니다. 베타는 이 Mac에 이미 있는 iOS 런타임들을 찾아내는데, 그중에 27.0은 있어도 27.1은 없습니다. 베타 아래의 xcodebuild -downloadPlatform iOS는 빠진 조각을 “iOS 27.1 Simulator (24A94401)”라고 지목하고, Apple의 mobile-asset 서비스를 통해 cryptex 디스크 이미지로 받아 옵니다. 반면 개발자 다운로드 페이지에 있는 디스크 이미지는 iOS 18.2 Simulator Runtime에서 멈춰 있습니다.34 첫 시도는 DVTDownloadable: Download FailedError Domain=DVTDownloadableErrorDomain Code=41 "Download failed."로 끝났습니다. 두 번째는 -buildVersion 24A94401을 붙여 실행했고, 런타임 크기를 7.85 GB로 표시하며 완료했으며, 그 뒤 simctl list runtimes에는 “iOS 27.1 (27.1 - 24A94401)”이 올라왔습니다. 디스크는 넉넉히 잡아 두십시오. 런타임은 Xcode 다운로드의 네 배입니다.3

iOS 27.1 beta가 도는 iPhone Duo 시뮬레이터의 외부 디스플레이, 첫 부팅 화면. 어두운 홈 화면 왼쪽 위에 설정 아이콘, 오른쪽 가장자리에 시계와 Wi-Fi 상태가 세로로 쌓여 있고, 오른쪽에 Dock 타일, 오른쪽 아래에 검색 버튼이 보인다

첫 부팅 화면의 iPhone Duo 시뮬레이터 외부 디스플레이, 1398 × 2034 픽셀. 상태 표시 묶음이 오른쪽 가장자리를 따라 세로로 내려갑니다. Apple의 Human Interface Guidelines가 iPhone Duo의 Dynamic Island와 상태 표시줄을 놓아 둔 바로 그 쪽입니다.10

27.1 SDK에 Duo API가 들어 있습니까?

9월 17일에 저는 Apple의 “Preparing your app for iPhone Duo” 가이드가 쓰는 이름들을 iOS 27.0 SDK에서 찾아보았고, 이 기기에만 해당하는 열 개는 하나도 찾지 못했습니다. 같은 방식, 그러니까 모듈 인터페이스와 헤더를 대상으로 한 단순 텍스트 검색을 27.1 SDK에 돌리면 열 개가 모두 나옵니다. 표의 행은 검색한 부분 문자열입니다. 그중 일곱 행이 열 개 중 아홉 개를 담고 있는데, 두 개의 reservedRegions 메서드와 두 개의 axisBehavior 멤버가 각각 한 행을 나눠 쓰기 때문입니다. 나머지 세 행은 그 이름들 뒤에 있는 타입으로, ReservedRegion, toolbarVerticalBehavior(_:)에 대응하는 ToolbarVerticalBehavior, preferredVerticalBarBehavior에 대응하는 UIVerticalBarBehavior입니다.4

검색한 부분 문자열 SwiftUICore 인터페이스 SwiftUI 인터페이스 UIKit 인터페이스 UIKit 헤더
ArrangementView 45 0 19 4개 파일
UIArrangementViewController 0 0 19 4개 파일
ReservedRegion 16 0 15 3개 파일
reservedRegions 2 0 5 1개 파일
ToolbarVerticalBehavior 0 5 0 0
UIVerticalBarBehavior 0 0 0 1개 파일
verticalBarEdge 0 0 0 1개 파일
toolbarVerticalEdge 1 0 0 0
axisBehavior 0 2 0 1개 파일
preferredVerticalBarBehavior 0 0 0 1개 파일

이 표에서 코드 작성에 영향을 주는 대목이 두 가지입니다. 첫째, SwiftUI 타입들은 SwiftUICore에 있는데, 이 모듈은 import SwiftUI가 다시 내보내므로 평범한 import만으로 닿습니다. 둘째, availability 속성이 플랫폼 범위에서 문서와 어긋납니다. SwiftUICore 인터페이스는 ArrangementView를, SwiftUI 인터페이스는 toolbarVerticalBehavior(_:)를 모두 @available(anyAppleOS 27.1, *) 아래에 선언합니다. anyAppleOS는 해당 버전의 모든 플랫폼을 뜻하는 Apple의 줄임 표기입니다. 반면 UIArrangementViewController.hUIView.hreservedRegionsOfKind: 메서드는 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1))API_UNAVAILABLE(watchos)를 달고 있습니다. UIVerticalBarEdge.h에서도 enum과 verticalBarEdge 트레이트는 같은 조합이지만, Leading과 Trailing 케이스만은 API_AVAILABLE(ios(27.1)) API_UNAVAILABLE(visionos) API_UNAVAILABLE(watchos, tvos)입니다. Apple의 문서 페이지는 다섯 개 모두 iOS 27.1과 iPadOS 27.1만 beta 표시로 적어 둡니다.47 iOS를 기준으로 쓰고, 나머지는 컴파일러가 알려 주게 두십시오.

가이드가 쓰는 이름 중 이미 27.0 SDK에 있던 세 개는 그대로입니다. presentationPlacement(_:)는 지금도 @available(anyAppleOS 27.0, *) 아래에 있고, backgroundExtensionEffect()는 iOS 26부터 계속 자리를 지키고 있습니다. 가이드가 이름을 든 두 개의 ToolbarItemPlacement 케이스 중 topBarPinnedTrailing@available(iOS 27.0, visionOS 27.0, *) 아래에 있고, cancellationAction에는 타입의 것 말고 따로 붙은 availability가 없습니다.4

시뮬레이터 프로파일은 두 디스플레이에 대해 무엇을 말합니까?

Apple이 베타와 함께 설치하는 디바이스 타입 iPhone Duo.simdevicetype/Library/Developer/CoreSimulator/Profiles/DeviceTypes 아래에 놓인 평범한 번들이고, 그 안의 프로퍼티 리스트 두 개가 사양표가 열어 둔 채 남긴 질문에 답해 줍니다.5

신원을 알려 주는 쪽은 profile.plist입니다. 모델 식별자는 iPhone19,4, 제품 클래스는 V68, 별칭은 com.apple.CoreSimulator.SimDeviceType.V68, minRuntimeVersion은 27.1이며, 27.1 이상 런타임에서는 이 기기를 기본으로 만든다는 규칙이 들어 있습니다. 하드웨어를 알려 주는 쪽은 capabilities.plist입니다. 모델 번호 A3447, HomeButtonType 2, DeviceSupportsDynamicIsland true, DeviceSupportsEnhancedMultitasking false, IsLargeFormatPhone true, CompatibleDeviceFallbackiPhone18,3, 기기 모서리 반경은 59, 그리고 내장 항목 두 개와 가상 항목 세 개가 담긴 displays 배열입니다.5

프로파일의 디스플레이 픽셀 스케일 포인트 네이티브 방향 모서리 반경 색 공간
primary(“LCD”, 스크린 1) 1398 × 2034 3 466 × 678 0 8, 59, 8, 59 P3
primary-1(“LCD-1”, 스크린 3) 2007 × 2853 3 669 × 951 270 네 모서리 모두 55 sRGB

첫 행은 외부 디스플레이이고 Apple의 사양표와 픽셀 단위까지 일치합니다. 둘째 행은 내부 디스플레이인데, 그 픽셀 수는 패널의 1878 × 2670이 아니라 App Store Connect의 스크린샷 크기인 2007 × 2853입니다. 즉 시뮬레이터는 내부 디스플레이를 3x 기준 669 × 951 포인트로 그리며, 이는 Duo 개발자 글이 9월 10일에 해 보이고 추론이라고 못 박았던 바로 그 산수입니다. 이제 Apple 자신의 프로파일이 그 숫자를 담고 있습니다. 네이티브 방향 270도는 내부 디스플레이가 가로가 네이티브라는 뜻이고, 기기를 펼치면 폭 951 포인트에 높이 669 포인트가 되며, 이는 Apple이 밝힌 펼친 상태의 치수와도 맞습니다. 남은 두 숫자는 하드웨어 값이 아니라 시뮬레이터 값입니다. 두 디스플레이 모두 인치당 460픽셀에 60 Hz로 적혀 있지만 사양표는 내부 패널에 430ppi를 줍니다. 그러니 hdpi는 자리를 채워 둔 값으로 여기십시오.5

프로파일은 모양도 함께 내놓습니다. 각 디스플레이는 프레임버퍼 마스크, 곧 보이는 영역을 담은 PDF를 참조합니다. 외부 디스플레이의 마스크는 모서리가 비대칭이고, 프로파일 값으로는 한쪽 긴 변이 8, 반대쪽이 59입니다. 제가 읽기로는 반경이 작은 쪽이 Apple 디자인 가이드가 설명하는 가운데 힌지와 만나는 쪽입니다. 내부 디스플레이의 마스크는 프로파일의 모서리 값 55를 그대로 쓴 평범한 둥근 사각형이고 전면 카메라를 위한 파임이 없습니다. 따라서 카메라로 인한 가림은 프레임버퍼 모양이 아니라 실행 시점의 예약 영역 API에서 온다는 뜻이 됩니다.510

시뮬레이터에는 무엇이 보입니까?

기기는 접힌 상태로 부팅합니다. 첫 부팅에서 외부 디스플레이에는 홈 화면이 뜨고, 내부 디스플레이의 프레임버퍼는 켜져 있지만 까맣습니다. simctl io enumerate는 프로파일의 이름 그대로 primary를 1398 × 2034로, primary-1을 2007 × 2853으로, 평소의 가상 스크린들과 나란히 열거합니다.6 저는 지오메트리와 size class, toolbarVerticalEdge 환경 값, 그리고 includeInactive를 붙여 두 종류의 예약 영역을 읽고, 세 가지 스타일 각각으로 ArrangementView를 감싸며, 내비게이션 툴바에 항목 여섯 개를 넣는 한 파일짜리 SwiftUI 프로브를 설치했습니다.6

iPhone Duo 시뮬레이터의 외부 디스플레이에 올라간 프로브 앱. 오른쪽 위 툴바에 공유 아이콘, 말줄임표 오버플로 버튼, 체크 표시가 있고, 값은 크기 386 × 510 포인트, size class는 compact와 regular, toolbarVerticalEdge는 nil, divisions 0에 occlusions 0. split arrangement에서 주 뷰가 보조 뷰 위에 있고, 오른쪽 가장자리에 시계와 Wi-Fi 상태가 쌓여 있다

외부 디스플레이의 프로브, Closed 포즈: 466 × 678 포인트, 폭은 compact, split arrangement는 위아래로, 툴바는 가로로.

Closed에서 프로브는 컴팩트한 iPhone이 보고할 법한 값을 그대로 보고합니다. UIScreen.main.bounds는 스케일 3의 466 × 678 포인트, size class는 폭 compact에 높이 regular, toolbarVerticalEdge는 nil, UIKit의 verticalBarEdge 트레이트는 raw value 0, 그리고 예약 영역을 묻는 두 질의는 비활성 영역을 포함해도 빈 배열을 돌려줍니다. 접은 포즈는 앱에 접힘 부분도 카메라도 드러내지 않는다는 뜻입니다. 내비게이션 스택 안의 GeometryReader가 잰 값은 386 × 510 포인트였고, 세이프 에어리어 인셋은 위 134, 아래 34, 좌우는 없었습니다. 제가 읽기로는 시스템이 가져간 폭 80 포인트가 상태 표시 묶음이 앉는 오른쪽 레일입니다. split arrangement는 주 뷰를 보조 뷰 위에 놓았는데, 이는 Apple 가이드가 설명하는 폭보다 높이가 큰 경우입니다. 툴바는 위쪽에 가로로 그려졌고, Share와 체크 표시 완료 버튼이 오버플로 버튼 옆에 있었으며, 보조 동작 네 개는 바에서 빠진 채 그 배치로 보아 메뉴 안에 들어가 있었습니다.67

포즈가 사는 곳은 Device Hub입니다. Duo 기기를 선택하면 그 창에 Rotate Right, Closed, Book, Open이 접근성 API로 누를 수 있는 버튼으로 나타나고, 이 절의 나머지도 그렇게 조작했습니다.6

Open은 앱을 내부 디스플레이의 네이티브 방향인 가로로 옮깁니다. 프로브는 폭 regular, 높이 regular를 보고하고, GeometryReader는 803 × 515 포인트를 재며, 세이프 에어리어 인셋은 위 134, 좌우 각각 34, 아래 20이었습니다. 폭에서 빠진 80 포인트는 접은 포즈와 같고, 제가 읽기로는 그 레일이 다시 나타난 것입니다. 이번에는 폭 951 포인트 화면의 오른쪽에 있고 그 안에 상태 표시 묶음이 들어 있습니다. split arrangement는 주 뷰와 보조 뷰를 나란히 놓는데, Apple 가이드가 말하는 높이보다 폭이 큰 경우입니다. 툴바는 오른쪽 위에 가로로 그려졌고, 여기서도 Share와 완료가 오버플로 버튼 옆에 있었으며 보조 동작 네 개는 바에서 빠져 있었습니다.6

Open 포즈, 가로 방향인 iPhone Duo 시뮬레이터의 내부 디스플레이에 올라간 프로브 앱. 크기 803 × 515 포인트, size class는 regular와 regular, toolbarVerticalEdge는 nil, divisions 0에 occlusions 0. split arrangement에서 주 뷰와 보조 뷰가 나란히 있고, 툴바는 오른쪽 위, 오른쪽 가장자리의 검은 레일에 시계와 Wi-Fi 상태가 들어 있다

Open 포즈, 내부 디스플레이, 2853 × 2007 픽셀: 양쪽 모두 regular, split arrangement는 나란히, 레일은 오른쪽에.

Rotate Right는 내부 디스플레이를 세로로 돌립니다. 그러면 프로브가 재는 값은 669 × 703 포인트이고, 양쪽 모두 regular이며, 인셋은 위 134, 아래 34, 좌우는 없습니다. 제가 읽기로는 80 포인트짜리 레일이 위쪽 가장자리로 옮겨 가 상태 표시 묶음이 그곳의 검은 띠에 앉은 것입니다. 그리고 컨테이너가 폭보다 높아졌는데도 split arrangement는 나란히 배치를 유지합니다.6

세로로 회전시킨 iPhone Duo 시뮬레이터의 내부 디스플레이에 올라간 프로브 앱. 크기 669 × 703 포인트, size class는 regular와 regular, split arrangement는 여전히 나란히, 위쪽을 가로지르는 검은 띠에 시계와 Wi-Fi 상태가 들어 있다

회전한 내부 디스플레이: 폭 669 포인트, 여전히 양쪽 모두 regular, 레일은 위쪽을 가로질러.

반쯤 접은 포즈인 Book이야말로 예약 영역 API가 제 몫을 해야 할 자리인데, 이 베타에서 제 프로브에게는 그러지 않았습니다. 앞에 아무 앱도 없는 상태로 Book을 누른 뒤 내부 디스플레이에는 홈 화면이 떴고, 다시 실행한 프로브는 Open일 때와 똑같이 803 × 515 포인트, 양쪽 모두 regular, 그리고 비활성 영역을 포함해도 divisions 0에 occlusions 0을 SwiftUI에서도 UIKit에서도 보고했습니다. 접은 포즈도 0을 보고합니다. reservedRegions가 접힘 부분이나 카메라를 돌려주는 포즈를 저는 찾지 못했고, 따라서 접힘에 맞춰 바뀌는 레이아웃은 이 베타의 시뮬레이터가 제게 보여 주지 않은 것입니다. Apple 가이드는 분할이 활성화되는 시점을 “when iPhone Duo is partially open,”(iPhone Duo가 반쯤 열렸을 때)이라고 설명하는데, 이것이 베타의 구멍인지 프로브의 구멍인지는 다음 베타로 넘어가는 질문입니다.67

모든 포즈에서 유지된 것이 두 가지 더 있습니다. 툴바는 한 번도 세로로 그려지지 않았습니다. toolbarVerticalEdge는 SwiftUI에서 nil이었고 verticalBarEdge는 UIKit에서 raw value 0이었으며, 접었을 때도 펼쳤을 때도 회전했을 때도 같았습니다. Apple 가이드가 설명하는 세로 바는 이 베타에서 내비게이션 스택의 툴바에는 나타나지 않았습니다. 그리고 UIScreen.main.bounds는 앱이 내부 디스플레이에 있는 동안에도 외부 디스플레이인 466 × 678 포인트를 답했습니다. Apple 가이드가 레이아웃 계산을 “based on your scene or containing view’s bounds rather than screen dimensions”(화면 치수가 아니라 씬 또는 포함 뷰의 bounds를 기준으로)라고 당부할 때 경고하는 함정이 바로 이것입니다. 메인 스크린은 지금 내가 올라가 있는 스크린이 아닙니다. 프로브를 빌드하면 컴파일러는 이미 'main' was deprecated in iOS 26.0이라고 말하는데, 그 이유가 이 기기입니다.67

다른 포즈로 돌아가는 길 하나는 통하지 않습니다. simctl io screenConfig로 스크린 전원을 끌 수는 있지만, 내부를 켜 둔 채 외부 디스플레이 전원을 꺼도 기기는 펼쳐지지 않았습니다. 대신 시뮬레이터의 시스템 셸이 죽었고, 이어진 simctl launch는 “The system shell probably crashed.”로 실패해 재부팅이 필요했습니다. 포즈는 Device Hub 창에 삽니다.6

이 베타가 아직 하지 못하는 일

Apple은 베타 자신의 노트에서 Simulator, Known Issues 아래에 제약 세 가지를 적어 두었습니다. “Initial Simulator launch can take several minutes.”(187708500), “StandBy is unavailable in the iPhone Duo Simulator runtime.”(187708663), “Running and debugging most app extensions is unavailable in the iPhone Duo Simulator runtime.”(187708767)입니다.2 StandBy 건은 그 화면을 노린 위젯이나 라이브 액티비티를 가진 사람에게 중요합니다. Apple의 발표는 이 기기가 “enters StandBy on either the outer or inner display”(외부든 내부든 어느 디스플레이에서나 StandBy로 들어간다)라고 말하고 그것을 “hub for widgets”(위젯의 허브)라고 부릅니다. 거기에 무엇이 나타나는지는 Duo 개발자 글에서 다루었고, 나중 베타가 이 제약을 풀기 전까지 이 기기의 StandBy는 실제 기기에서 확인할 일입니다.11

두 건이 더 Mac Catalyst, Known Issues 아래에 있는데, 이 API들을 채택하면서 Mac용으로도 빌드하는 앱을 정면으로 칩니다. 첫째는 “Projects that use APIs specific to iOS 27.1 show compile errors when building for Mac Catalyst (“undeclared identifier”, “not found”, “has no member”, “cannot find”, etc). (185924957)”이고, Apple의 우회책은 Swift에서는 #if !targetEnvironment(macCatalyst), Objective-C에서는 #if !TARGET_OS_MACCATALYST입니다. 둘째는 “Projects that target iOS 27.1 show no Mac Catalyst run destination available. (187046347)”이고, 우회책은 “Add a Mac Catalyst 27.0 minimum deployment in target settings.”입니다.2 Xcode 27.2 베타 노트는 반대 방향에서 세 번째를 더합니다. “macOS, watchOS, tvOS, and visionOS SDKs in Xcode 27.2 incorrectly report 27.1 as a valid deployment target,” 그리고 “Mac Catalyst builds with a 27.1 or 27.2 deployment target may be unable to use newly introduced API.” (187160501)입니다.8

이번 주에 제가 할 일

  1. 베타를 Xcode 27.0 위에 덮어쓰지 말고 그 옆에 설치합니다. xip을 펼치고, 앱 이름을 바꾸고, 명령줄 빌드를 위해 DEVELOPER_DIR를 그쪽으로 돌립니다. 베타 노트에 27.0 툴체인을 바꾸는 항목은 하나도 없고, 컴파일러와 링커의 버전 문자열도 같습니다.4
  2. 필요해지기 전에 런타임 다운로드를 시작합니다. 베타 아래에서 xcodebuild -downloadPlatform iOS를 실행하고, 실패하면 다시 시도하십시오. iPhone Duo 디바이스 타입을 부팅 가능하게 만드는 것이 이 런타임이고, 게다가 Apple은 첫 실행에 몇 분이 걸린다고 경고합니다.23
  3. Mac Catalyst 타깃을 포함한 채로 27.1 SDK에 대고 한 번 빌드합니다. 새 API를 #if !targetEnvironment(macCatalyst)로 막을지, Catalyst 최소 배포 버전을 27.0으로 올릴지 정하기 전에 Apple이 지목한 진단 두 가지를 읽어 두십시오.2
  4. 미리보기와 테스트의 기준 크기로 프로파일의 숫자를 씁니다. 접었을 때 466 × 678 포인트, 펼쳤을 때 669 × 951 포인트, 내부 디스플레이는 가로가 네이티브입니다. 베타의 Previews 노트는 캔버스 오버라이드 선택기에 “for previewing content on a device’s alternative display.”(기기의 다른 디스플레이에서 콘텐츠를 미리 보기 위해) Display 그룹을 추가했다고 적습니다. (182598534)25
  5. 개발 중에는 포즈마다 예약 영역을 로그로 남깁니다. .includeInactive를 넘긴 reservedRegions(kind:options:layoutDirectionBehavior:)는 접힘 부분과 카메라를 활성일 수도 비활성일 수도 있는 ReservedRegion 값으로 돌려준다고 문서에 적혀 있습니다. 이 베타에서는 모든 포즈가 아무것도 돌려주지 않았으니, onChange(of: proxy.size)에 로그 한 줄을 넣어 두면 어느 포즈가 언제부터 그것을 보고하기 시작하는지 알 수 있습니다.67

자주 묻는 질문

Xcode 27.1 beta에 iPhone Duo 시뮬레이터가 들어 있습니까?

그렇습니다. 베타는 iPhone Duo 디바이스 타입, 곧 com.apple.CoreSimulator.SimDeviceType.iPhone-Duo를 설치합니다. 그 프로파일은 iOS 27.1 런타임을 요구하고, 그 런타임은 Xcode가 xcodebuild -downloadPlatform iOS로 따로 내려받습니다. Apple의 노트는 첫 실행이 “can take several minutes”(몇 분이 걸릴 수 있다)라고, 그리고 그 런타임에서는 StandBy와 대부분의 앱 익스텐션을 쓸 수 없다고 경고합니다.235

Xcode 27 옆에 Xcode 27.1 beta를 어떻게 설치합니까?

xip --expand로 xip을 펼치고, 나온 앱을 /Applications/Xcode-27.1-beta.app처럼 버전이 붙은 이름으로 옮긴 다음, xcodebuildxcrun, swiftc를 위해 DEVELOPER_DIR를 그 앱의 Contents/Developer 폴더로 설정하십시오. 베타는 macOS Tahoe 26.6 이상을 요구하며, 이는 Xcode 27.0과 같은 하한입니다.24

iPhone Duo 내부 디스플레이는 포인트로 얼마입니까?

669 × 951 포인트입니다. 시뮬레이터의 디바이스 프로파일이 내부 디스플레이를 스케일 3의 2007 × 2853 픽셀에 가로가 네이티브인 방향으로 정의합니다. 외부 디스플레이는 스케일 3의 1398 × 2034 픽셀에서 나온 466 × 678 포인트입니다.5

Xcode 27.1 beta가 iOS 27.0 SDK나 Xcode 27 툴체인을 바꿉니까?

아닙니다. Swift 컴파일러와 링커는 Xcode 27.0과 같은 버전 문자열을 보고하고, 베타의 릴리스 노트에는 Mac Catalyst, Previews, Simulator 세 절뿐이며 그중 어느 것도 툴체인을 건드리지 않습니다. iOS 27.1 SDK는 추가된 것이고, 기기용과 시뮬레이터용 SDK 양쪽에서 빌드 24A94403으로 식별됩니다.24

iPhone Duo는 언제, 무엇 위에서 출시됩니까?

10월 23일, iOS 27.1 위에서입니다. Apple의 9월 16일 뉴스 글에 이렇게 적혀 있습니다. “When iPhone Duo becomes available on October 23, it will run iOS 27.1.”9

출처


  1. Apple, Releases, 2026년 9월 19일에 받은 RSS 피드: “Xcode 27.1 beta (27A9269)”는 Fri, 18 Sep 2026 10:00:00 PDT 자, “TestFlight Update”는 Fri, 18 Sep 2026 14:00:00 PDT 자. Apple, App Store Connect 릴리스 노트, 2026년 9월 18일, TestFlight 업데이트, 전문 인용. 

  2. Apple, Xcode 27.1 Beta Release Notes, 2026년 9월 19일에 문서 JSON 엔드포인트로 받음: Overview 인용, Mac Catalyst의 Known Issues 185924957과 187046347을 각각의 우회책과 함께 인용, Previews의 New Features 182598534 인용, Simulator의 Known Issues 187708500, 187708663, 187708767 인용. 이 노트에 다른 절은 없습니다. 

  3. 글쓴이가 macOS 26.6.2(25G83)에서 2026년 9월 19일에 진행한 런타임 다운로드, DEVELOPER_DIR는 Xcode 27.1 beta로 설정: xcodebuild -downloadPlatform iOS는 이미 설치된 27.0 런타임에 대해 “iOS is already downloaded.”를 출력한 뒤 “Downloading iOS 27.1 Simulator (24A94401) (arm64)”를 출력했고, 이어서 DVTDownloadable: Download Failed. Downloadable: DVTDownloadable(identifier: 0a4e7582-0061-5907-bea9-fe234c1f9392, version: 27.1.0.1, category: simulator, contentType: cryptexDiskImage, downloadMethod: mobileAsset, platform: com.apple.platform.iphoneos)Error Domain=DVTDownloadableErrorDomain Code=41 "Download failed."가 나왔습니다. 재시도한 xcodebuild -downloadPlatform iOS -buildVersion 24A94401은 “Downloading iOS 27.1 Simulator (24A94401) (arm64): 0.0% (66 kB of 7.85 GB)”를 출력하고 완료했으며, 그 뒤 xcrun simctl list runtimes에 “iOS 27.1 (27.1 - 24A94401) - com.apple.CoreSimulator.SimRuntime.iOS-27-1”이 올라왔습니다. 같은 날 로그인한 상태로 Apple 개발자 다운로드 페이지를 “Simulator Runtime”으로 검색하면 iOS 18.2 Simulator Runtime보다 새로운 디스크 이미지는 없습니다. 

  4. 글쓴이가 2026년 9월 19일에 /Applications/Xcode-27.1-beta.app을 살펴본 결과: xcodebuild -versionXcode 27.1Build version 27A9269를 출력하고, xcrun --sdk iphoneos --show-sdk-versionxcrun --sdk iphonesimulator --show-sdk-version은 둘 다 27.1을 출력합니다. 두 SDK의 SystemVersion.plistProductBuildVersion 24A94403과 ProductVersion 27.1을 담고 있습니다. xcrun swift --versionApple Swift version 6.4 (swiftlang-6.4.0.34.1 clang-2100.3.34.1)을, xcrun ld -vld-27037.1을 출력하는데, 같은 Mac에서 Xcode 27.0(27A266a)이 출력하는 버전 문자열과 같습니다. Xcode_27.1_beta.xip은 2,027,292,809바이트이고, pkgutil --check-signature는 Software Update 인증서 체인과 함께 “signed Apple Software”라고 보고합니다. 펼친 앱에 대한 du -sk는 3,813,336 KB, /Applications/Xcode-27.app에 펼친 Xcode 27.0(27A266a)은 3,804,188 KB입니다. 이름 개수는 iPhoneOS SDK의 SwiftUICore.swiftmodule/arm64e-apple-ios.swiftinterface, SwiftUI.swiftmodule/arm64e-apple-ios.swiftinterface, UIKit.swiftmodule/arm64e-apple-ios.swiftinterface에 대한 grep -cUIKit.framework/Headers 전체에 대한 grep -rl 파일 개수입니다. availability 속성도 같은 파일들에서 읽었습니다. SwiftUICore 인터페이스의 public struct ArrangementView< 위, 그리고 SwiftUI 인터페이스에서 func toolbarVerticalBehavior를 선언하는 extension SwiftUICore.View 위에는 @available(anyAppleOS 27.1, *)가 있습니다. UIArrangementViewController.h, UIView.h의 두 reservedRegionsOfKind: 선언, 그리고 UIVerticalBarEdge enum과 verticalBarEdge 트레이트에는 API_AVAILABLE(ios(27.1), tvos(27.1), visionos(27.1))에 이어 API_UNAVAILABLE(watchos)가 붙어 있고, 그 UIVerticalBarEdgeLeadingUIVerticalBarEdgeTrailing 케이스에는 API_AVAILABLE(ios(27.1)) API_UNAVAILABLE(visionos) API_UNAVAILABLE(watchos, tvos)가 붙어 있습니다. func presentationPlacement 위에는 @available(anyAppleOS 27.0, *), public static let topBarPinnedTrailing 위에는 @available(iOS 27.0, visionOS 27.0, *), public static let cancellationAction 위에는 속성이 없습니다. 첫 실행에 대해서는, 베타의 DEVELOPER_DIR 아래에서 처음 실행한 xcodebuild -version이 2분 타임아웃을 넘겼고, /var/log/install.log에는 9월 19일 16시 01분 54초에 xcodebuild가 PackageKit 설치를 큐에 넣어 Xcode-27.1-beta.app/Contents/Resources/Packages에서 CoreTypes.pkgXcodeSystemResources.pkg를 풀고 16시 03분 04초에 끝낸 기록이 남아 있습니다. 그 뒤 xcodebuild -checkFirstLaunchStatus는 0을 반환했습니다. 

  5. /Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone Duo.simdevicetype, Xcode 27.1 beta가 설치했고 2026년 9월 19일에 plutil -convert xml1로 읽었습니다. profile.plist: modelIdentifier iPhone19,4, productClass V68, aliases com.apple.CoreSimulator.SimDeviceType.V68, minRuntimeVersion 27.1, createByDefaultForRuntimeVersions의 versionMin 27.1. capabilities.plist: ModelNumber A3447, ThinningProductType iPhone19,4, CompatibleDeviceFallback iPhone18,3, DeviceCornerRadius 59, HomeButtonType 2, DeviceSupportsDynamicIsland true, DeviceSupportsEnhancedMultitasking false, IsLargeFormatPhone true. ScreenDimensionsCapability는 main-screen-width 1398, main-screen-height 2034, main-screen-pitch 460, main-screen-scale 3. displaysprimary(displayName LCD, screenID 1, width 1398, height 2034, scale 3, hdpi와 vdpi 460, refreshRate 60, nativeOrientation 0, cornerRadiusUL 8, UR 59, LL 8, LR 59, colorspace P3)와 primary-1(displayName LCD-1, screenID 3, width 2007, height 2853, scale 3, hdpi와 vdpi 460, refreshRate 60, nativeOrientation 270, 네 모서리 반경 모두 55, colorspace sRGB), 여기에 external-0(TVOut), wireless0(carPlay), resizable(scene)이 더 있습니다. 두 개의 framebufferMaskIdentifier PDF는 qlmanage로 렌더링해 살펴보았습니다. 패널에 대한 Apple 사양표 수치는 Duo 개발자 글에 있습니다. 베타 아래의 xcrun simctl list devicetypes는 “iPhone Duo (com.apple.CoreSimulator.SimDeviceType.iPhone-Duo)”를 나열합니다. 

  6. 글쓴이가 macOS 26.6.2(25G83)에서 2026년 9월 19일과 20일에 진행한 실행. 기기: simctl create "Duo-27.1" com.apple.CoreSimulator.SimDeviceType.iPhone-Duo com.apple.CoreSimulator.SimRuntime.iOS-27-1로 만들고 simctl bootsimctl bootstatus -b로 부팅했습니다(이 Mac에서 1분 남짓). simctl io <udid> enumerate는 디스플레이 클래스 0의 com.apple.framebuffer.display 포트 두 개를 1398 × 2034와 2007 × 2853으로 나열하고, Connected Screens 아래에는 “LCD-1”이 기기 이름 primary-1, 스크린 ID 3, 픽셀 크기 {2007, 2853}으로 올라옵니다. 프로브: DuoProbe, 한 파일짜리 SwiftUI 앱으로 Xcode 27.1 beta 아래에서 xcrun swiftc -sdk <iPhoneSimulator.sdk> -target arm64-apple-ios27.1-simulator -parse-as-library로 빌드하고 simctl install로 설치, simctl launch --console-pty로 실행했으며, 스크린샷은 simctl io <udid> screenshot --mask=alpha --display=primary--display=primary-1로 찍었습니다. 접은 포즈의 콘솔 줄: DUOPROBE screen=(466.0, 678.0) scale=3.0 idiom=0 model=iPhone name=Duo-27.1, DUOPROBE size=386x510 h=compact v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 0.0, bottom: 34.0, trailing: 0.0), DUOPROBE uikit bounds=(354.0, 44.0) divisions=0 occlusions=0 verticalBarEdge=UIVerticalBarEdge(rawValue: 0). division[이나 occlusion[ 줄은 없습니다. --display=primary-1 스크린샷은 까맣습니다. 스크린 전원: simctl io <udid> screenConfig --display=primary power off는 “Screen 1 power state set to off”를 출력했고, 다음 simctl launchFBSOpenApplicationServiceErrorDomain 코드 5, “The system shell probably crashed.”로 실패했으며, simctl shutdownboot으로 기기를 복구했습니다. 포즈별 실행은 9월 20일에 두 차례 시리즈로 진행했고, 둘 다 Device Hub가 선택된 기기에 대해 내놓는 버튼에 접근성 API의 AXPress 동작을 보내 Rotate Right, Closed, Book, Open을 눌렀으며, 둘 다 27.2 베타의 simctl 명령줄 도구(그 스크립트가 설정하는 DEVELOPER_DIR)로 27.1 베타의 런타임, 디바이스 타입, Device Hub를 상대로 구동했습니다. 첫 시리즈에서는 다음 버튼을 누를 때 이전 포즈의 프로브가 아직 실행 중이었고, 그 뒤 종료했다가 다시 실행하면서 콘솔을 12초 동안 캡처하고 두 디스플레이의 스크린샷을 찍었습니다. 아래의 회전 시 수치와 전환 중 줄은 이 시리즈에서 나온 것입니다. 둘째 시리즈에서는 캡처할 때마다 프로브를 종료해, 다음 버튼을 누를 때 앞에 앱이 없도록 했습니다. 재실행 전 스크린샷은 이 시리즈에서 나온 것입니다. Open: DUOPROBE size=803x515 h=regular v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 34.0, bottom: 20.0, trailing: 34.0), DUOPROBE uikit bounds=(771.0, 44.0) divisions=0 occlusions=0 verticalBarEdge=UIVerticalBarEdge(rawValue: 0), 그리고 DUOPROBE screen=(466.0, 678.0). --display=primary-1 스크린샷에는 프로브가 보이고 --display=primary는 까맣습니다. Book: 재실행 후 같은 세 줄. 버튼을 누른 뒤 재실행 전에 찍은 내부 디스플레이 스크린샷에는, 실행 중인 앱이 없는 상태로 홈 화면이 보입니다. Closed: 위의 접은 포즈 줄들. Rotate Right 다음의 Open: DUOPROBE size=669x703 h=regular v=regular verticalEdge=nil safe=EdgeInsets(top: 134.0, leading: 0.0, bottom: 34.0, trailing: 0.0)uikit bounds=(637.0, 44.0), 내부 디스플레이 스크린샷은 세로 방향입니다. division[이나 occlusion[ 줄을 출력한 실행은 하나도 없습니다. 회전한 접은 상태는 포즈가 바뀌는 도중의 전환 줄로만 나타났고(DUOPROBE size=610x232 h=compact v=compact ... screen=(678.0, 466.0)), 위의 수치에는 넣지 않았습니다. 

  7. Apple, 2026년 9월 19일에 받은 문서 JSON: ArrangementView, UIArrangementViewController, reservedRegions(kind:options:layoutDirectionBehavior:), reservedRegions(kind:options:), toolbarVerticalBehavior(_:). 각 페이지의 플랫폼 availability는 iOS 27.1과 iPadOS 27.1이며 beta 표시입니다. Apple, Preparing your app for iPhone Duo, 같은 날 받음, 가이드가 쓰는 이름의 출처입니다. 

  8. Apple, Xcode 27.2 Beta Release Notes, 2026년 9월 19일 받음, SDK, Known Issues, 187160501 인용. 

  9. Apple, “Get ready with the latest beta releases”, 뉴스, 2026년 9월 16일, “Note about iOS 27.1 and iPhone Duo” 인용. 

  10. Apple, Designing for iPhone Duo, Human Interface Guidelines, 2026년 9월 20일에 문서 JSON 엔드포인트로 받음: “Controls on the side include both system and app elements: the Dynamic Island, the status bar, the toolbar (including navigation buttons), and the tab bar.” 그리고 “A hinge in the center lets people open and close the device”. 

  11. Apple Newsroom, Apple unveils iPhone Duo, 2026년 9월 9일, 2026년 9월 20일 받음: StandBy 문단에서 “Set iPhone Duo down and it enters StandBy on either the outer or inner display”와 “hub for widgets” 인용. 

관련 게시물

arm64e.x1: Apple의 검사된 포인터 연산 슬라이스

iOS 27 RC 릴리스 노트에 arm64e.x1이 추가됐습니다. A20 Pro, M6, S11에서 동작하는 검사된 포인터 연산(CPA2), clang이 생성하는 명령, Xcode의 네 가지 스위치, 대응 하드웨어 …

15 분 소요

iOS 27.0 릴리스 노트: 사용 중단, 동작 변경, 수정 사항

iOS 27.0(24A437)이 9월 14일에 출시되었습니다. 개발자 관점에서 노트를 읽습니다. 사용 중단 11건, 27 SDK로 빌드하는 순간 바뀌는 동작, 그리고 제가 직접 검증한 수정 1건입니다.

34 분 소요

iPhone Duo를 위한 디자인: 움직이는 것, 나뉘는 것, 그대로 있는 것

Apple의 iPhone Duo 디자인 가이드와 세 편의 Tech Talk를 규칙으로 읽습니다. 포즈별 레이아웃이 아닌 두 개의 사이즈 클래스, 접힘부에서의 변위, arrangement, 그리고 사이드 바.

17 분 소요