스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Xcode를 사용한 멀티 플랫폼 앱 개발
Xcode 14를 사용하여 다양한 Apple 플랫폼을 위한 앱을 빌드하는 방법을 알아보세요. 앱 타겟을 간소화하고, 공통 코드베이스를 유지하며, 기본적으로 설정을 공유하는 방법을 보여드리겠습니다. 또한 설정 및 코드의 상태를 조절하여 각 플랫폼에 맞게 앱을 맞춤화하는 방법을 살펴보겠습니다.
리소스
관련 비디오
WWDC22
-
다운로드
안녕하세요, 전 저는 Xcode 팀의 디자이너인 Jake예요 Xcode 14의 멀티플랫폼 앱 개발은 한 걸음 더 나아가고 있어요 이제 단일 앱 대상은 단일 공통 코드베이스를 유지하고 기본적으로 설정을 공유하고 필요한 곳에서 조건을 지정가능한 새로운 방법을 허용하면서 여러 플랫폼에서 훨씬 더 많은 대상을 지원할 수 있죠 먼저 다중 플랫폼 앱 타겟이 무엇이며 어떤 경우에 가장 잘 작동하는지 알아볼게요
다음으로 여러 대상과 플랫폼을 지원하도록 프로젝트를 수정한 후 새 플랫폼에서 빌드 후 실행하도록 프로젝트를 업데이트할게요
지원되는 각 플랫폼에서 앱이 멋지게 보이는지 확인한 다음…
마지막으로 Xcode Cloud를 프로젝트 변경 사항과 통합할께요
먼저 앱이 여러 플랫폼을 지원할 수 있도록 하기 위해 어떤 기술을 사용하는지를 살펴볼게요 Xcode 14 이전에는 앱이 iOS 및 macOS를 지원하도록 하려면 두 개의 개별 타깃이 필요했어요 프로젝트에 상당히 다른 코드베이스가 필요하거나 서로 다른 플랫폼 간에 설정을 거의 공유하지 않거나 각 앱 타깃이 서로 다른 기본 기술에 크게 의존할 때 유용하죠
만약 여러분의 프로젝트도 이런 경우라면 가장 좋은 방법은 각 플랫폼에 대해 별도의 타깃을 계속 사용하는 것이에요 Xcode 14의 단일 앱 대상은 iPhone iPad, Mac 및 Apple TV 같은 다양한 대상에 대한 지원을 선언할 수 있죠 이는 공통 코드베이스를 사용하고 모든 대상에서 대부분의 설정을 공유하는 동시에 필요 시 사용자 정의할 수 있는 앱에 적합해요 Xcode 14에서 멀티플랫폼 앱이 어떻게 작동하는지 살펴볼게요 만약 처음부터 시작한다면 Xcode에서 새 프로젝트를 만들 때 새롭고 향상된 멀티플랫폼 앱 템플릿을 사용하는 게 좋아요
멀티플랫폼 앱 템플릿은 수명 주기와 인터페이스에 SwiftUI를 사용하며, 기본적으로 iPhone iPad 및 Mac을 지원하도록 구성된 타깃으로 시작하죠 이건 새로운 프로젝트를 위한 환상적인 구성이에요 우리는 SwiftUI를 사용하기 때문에 각 플랫폼 SDK의 전체 기능 세트에 액세스할 수 있으므로 각 플랫폼이 제공하는 것을 활용하는 멋진 새 앱을 만들 수 있어요 더불어 기존 프로젝트는 앱 타깃에서 여러 대상에 대한 지원을 선언할 수도 있고 SwiftUI를 사용하여 각 플랫폼 SDK의 모든 기능에 액세스할 수도 있죠 이제 기존 iOS 앱에 Mac 대상을 추가하는 방법을 살펴볼게요 전 Food Truck 앱을 만들고 있는데 iPhone과 iPad에서 잘 작동하죠 저는 이 iOS 앱에 매우 만족하는데요 그래서 이 앱을 Mac으로 가져와 플랫폼과 그 기능을 쓰고 싶어요 우선 Xcode에서 프로젝트가 어떻게 보이는지 살펴볼게요
제 앱 대상을 살펴보면 앱이 지원하는 모든 대상 목록을 볼 수 있어요
여기 이미 iPad용으로 설계된 Mac 대상이 있으니 Apple silicon이 있는 Mac에서 미수정된 iOS 앱을 실행할 수 있죠 이것도 Mac 지원을 시작하는 좋은 방법이지만 전 Mac 지원을 다음 단계로 끌어올리고 싶어요 말하자면 'Designed for Mac' 환경을 추가하는 거죠
그럼 지원 대상 목록을 쉽게 편집하고 앱에 Mac 대상을 추가할 수 있어요 Mac 대상에 대한 몇 가지 옵션이 있는데 Mac, Mac Catalyst 및 Designed for iPad는 이미 제 앱이 지원하기 때문에 마지막 옵션은 회색으로 표시되죠
Mac과 Mac Catalyst 중에서 하나를 선택하는 것은 주로 우리가 가장 쓰고 싶어하는 기술이 뭔지를 의미해요 만약 앱이 앱 핵심에서 UIKit 또는 Storyboard를 많이 사용했다면 Mac Catalyst는 기존 iPad 앱을 호환 가능한 Mac 앱으로 변환하는 좋은 방법이 될 거예요 하지만 우리 앱은 'Mac 옵션'을 Mac 앱 제작에 가장 적합한 선택이 되도록 하는 SwiftUI를 사용하죠 제한 없이 macOS SDK의 모든 기능을 사용할 수 있는 것은 물론 보자마자 놀라운 Mac의 룩 앤드 필을 느낄 수 있을 거예요 즉 iOS 앱에서 UIKit을 사용하고 macOS 앱에서 AppKit을 자유롭게 사용하면서 유연한 작업을 경험해 볼 수 있을 거예요 이 내용을 염두에 두신 다음 이제는 SwiftUI 작업을 위한 최상의 옵션인 Mac을 선택해 볼게요 선택하고 나면 Xcode가 Mac 지원을 위해 프로젝트를 준비하는 데 필요한 몇 가지 변경 사항을 알려줄 거예요 이 경우 Xcode는 Mac에서 지원되는 종속성과 프레임워크만 포함하도록 대상을 업데이트합니다 Xcode는 제 코드를 변경하지 않기 때문에 Mac에서 사용할 수 없는 API를 호출하는 경우 해당 문제를 직접 해결해야 하죠 Mac 옵션을 선택하면 지원 대상 목록에 추가되고 Xcode에서 개발할 때 Mac 대상이 두 개 이상인 경우도 유효해요 이것은 'Mac Catalyst' 또는 'Designed for iPad'에서 전체 Mac 앱으로 전환할 때 특히 유용하죠
즉, Xcode 내에서 각 Mac 제품을 계속 테스트할 수 있다는 의미죠 그리고 앱 개발에 반드시 한 가지 방법만 선택하는 건 아니에요 하지만 만약 제 기본 Mac 앱을 App Store에 게시한다면 고객이 제 iPad용 앱을 더 이상 사용할 수 없으니 Xcode는 이 대상을 제거하는 빠른 방법을 제공하는 거죠 그렇지만 기본 Mac 환경에 만족하게 되면 이 대상을 제거하는 것을 고려할 것 입니다 처음부터 시작하든 기존 앱에 새 대상을 추가하든 Xcode에서 단일 타깃을 사용하면 기본적으로 코드를 공유하고 설정을 빌드할 수 있어요 앱의 디스플레이 이름이나 최소 배포 버전과 같은 개별 설정을 사용자 지정하려는 경우도 있을 텐데요 Xcode 14의 향상된 타깃 편집기로 이를 수행하는 방법을 살펴볼게요 많은 앱 대상 설정에는 값을 조건화하는 방법이 포함되죠 지원되는 설정에서는 프로젝트의 각 빌드 구성에 대한 기본값을 설정할 수 있는 편집기를 표시할 수 있어요 저는 사용자 지정 베타 구성을 추가했고 새 Xcode 프로젝트와 함께 제공되는 표준 디버그 및 릴리스 구성도 있어요 베타 구성으로 빌드할 때 앱에 다른 디스플레이 이름을 지정하고 싶다면 바로 여기에서 이름을 편집할 수 있어요 입력을 하면 Xcode에서 앱의 디스플레이 이름이 가능한 모든 디스플레이 이름 값의 readout으로 대체된 것을 볼 수 있을 거예요 필요한 경우 조건을 추가하여 사용 중인 SDK에 따라 값을 지정할 수도 있죠 이를 통해 Mac용으로 빌드하면 베타 구성에 대한 특정 이름을 설정할 수 있어요
좋아요, 이제 일반 탭에서 수정하려는 작업이 끝난 것 같네요 다른 변경 사항에 대해서는 Signing 및 Capabilities 탭을 통해 살펴볼게요
다행인 건 Automatic Signing가 켜져 있으면 더 무언가를 할 필요가 없다는 거예요 제가 Mac 대상을 추가할 때 Mac에 필요한 Signing Certificate와 Provisioning Profile이 이미 생성되었거든요 제 iOS 및 macOS 앱 제품은 기본적으로 동일한 번들 식별자를 사용하는데 이는 App Store에 게시할 때 Universal Purchase에 사용할 수 있음을 의미하기 때문에 정말 좋아요 제 iOS 앱을 구매하는 사람들은 Mac 앱도 자동으로 받는 거죠 앱은 푸시 알림과 같은 기능도 사용합니다 iOS 앱에 사용했던 모든 기능 중 macOS 앱에 적용할 수 있는 모든 것은 추가 작업 없이 적용되고 단일 entitlements 파일로 결합되기도 합니다 이제 앱에 여러 대상에 대한 지원을 추가했으니 다음 목표는 앱을 빌드하는 것이겠죠 특히 새로운 Mac 지원처럼 새로운 SDK가 있다면 새로운 대상을 위한 앱을 빌드하는 데 문제가 발생하는 것은 일반적인 거예요 그러면 이제 이러한 일반적인 문제 중 몇 가지를 살펴볼게요 일부 프레임워크는 모든 플랫폼에서 사용할 수 없습니다 그래서 사용할 수 없는 프레임워크를 가져오거나 연결하고 있지 않은지 확인해야 하죠 Xcode는 새 대상에 대한 지원을 추가할 때 코드를 변경하지 않기 때문에 앱 설정을 조건화한 방법과 유사하게 SDK를 기반으로 코드를 조건화해야 해요 이건 API도 마찬가지입니다 일부 기능은 빌드 중인 SDK에 따라 사용할 수 없는 것으로 표시되죠 Swift는 우리가 빌드하고 있는 SDK에 사용할 수 있는 기능만 포함하도록 코드의 일부를 조건화하는 방법을 제공해요 Xcode를 사용하면 일부 SDK용으로 빌드할 때 개별 파일을 컴파일해야 하는지 여부도 지정할 수 있어요 만약 지금 제가 프로젝트를 빌드하려고 하면… 문제는 없어 보이네요 iOS SDK를 사용하는 도구 모음에 대상이 선택되어 있기 때문이에요 macOS SDK에 빌드하려면 목록에서 'My Mac'을 선택해야 합니다
이제 빌드에서 몇 가지 새로운 문제가 드러났고 예상한 대로 주로 가용성과 관련이 있군요 제 파일 중 하나는 Mac에서 쓰지 못하는 ARKit를 가져오고 있어요 이 import 구문을 #if canImport로 감싸서 조건부로 지정할 수 있죠
이것은 프레임워크를 사용할 수 있는 플랫폼 목록을 관리하지 않는 경우에 유용하고 만약 사용할 수 없다면 포함하지 마세요 하지만 전 이 파일 전체에서 계속 ARKit을 사용하고 있기 때문에 때로는 SDK에 대해 전체 파일을 조건화하는 것 더 합리적이라 할 수 있죠 만약 대상으로 돌아가서 Build Phases 탭으로 이동하면 제 파일을 검색할 수 있고…
iOS용으로만 컴파일해야 한다고 지정할 수 있죠
빌드 후 이러한 변경을 수행하면 Xcode에서 새로운 문제를 보고하는데요 Mac에서 사용할 수 있는 프레임워크인 SwiftUI에는 사용할 수 없다고 표시되는 기능이 있어요 특히 iOS에선 EditMode를 사용하여 사용자가 Tables and Lists에서 콘텐츠를 편집하고 선택할 수 있지만 macOS에는 EditMode가 없어요 사용자는 이미 Mac에서 콘텐츠 행을 자유롭게 선택하고 편집할 수 있으니 이 코드는 iOS에서만 실행되게 할게요 제 환경 속성은 물론 EditMode를 사용한 어느 위치든 조건화를 할 수 있습니다
이제 이 onChange 모디파이어와 같이 이 속성을 사용하고 있던 모든 위치도 조건이 지정되었는지 확인해야 해요 전체 모디파이어를 'if os' 조건으로 감쌀 수도 있어요
마지막으로 iOS 전용 도구 모음의 EditButton을 사용하도록 할게요
자, 그럼 이제 앱을 실행해 볼게요
아, 되는군요! 앱이 빌드되었고 Mac에서 실행되고 있어요 하지만 앱이 새로운 플랫폼에서 빌드되고 실행된다고 해서 작업이 끝난 것은 아니에요 새 플랫폼의 사용자가 기대하는 것에 맞게 앱 경험을 개선해야 하는 경우도 있을 거니까요 더불어 iOS 전용 기능을 제거하는 것만이 끝은 아니죠 이제는 macOS SDK의 모든 기능을 사용할 수 있어요 이제 제 앱이 Mac에서 실행되는 것을 보니 새로운 맥락에서 무언가 자연스럽게 느껴지지 않는 것 같은 이상한 기분이 드네요 이 그리드 보기에서 도넛이 너무 커 보이는 것 같아요 왜냐하면 그리드 항목이 터치용으로 설계되었기 때문이죠 이와 같은 상황은 UI 요소의 포인트 크기를 선언하거나 단일 플랫폼만 생각하고 컨트롤을 사용자 지정할 때 발생하죠 Mac에서는 훨씬 더 정확한 포인팅 장치가 있으므로 버튼이나 축소판을 너무 크게 만들 필요가 없어요 이것은 우리가 빌드하는 SDK에 따라 달라지도록 프로젝트의 상수를 조건화하는 좋은 경우라 할 수 있어요 앱을 다른 플랫폼으로 가져올 때 우리의 새로운 플랫폼의 기대에 따라 이런 선택의 많은 부분을 재고하는 게 중요해요 이번에는 빌드 중인 SDK에 따라 다른 값을 지정하는 방법을 살펴볼게요 제가 자주 사용하는 기술 중 하나는 상수 계산 속성을 만들고 '#if os'를 사용하여 반환되는 내용을 조건화하는 것이에요 이것을 계산된 속성으로 변환하고 이전에 상수였던 것을 반환해 볼게요... 하지만 iOS에서만 해당 값을 반환하도록 할게요
아, 80이 훨씬 자연스럽게 사이즈가 느껴지네요
이제 macOS SDK를 사용하는 것과 관련하여 SwiftUI에는 Menu Bar에 자체 UI 요소를 추가할 수 있는 멋진 새 기능이 생겼네요 사용자가 빠르고 쉽게 액세스할 수 있도록 제 앱에 대한 요약 보기가 가능한데요 App 선언으로 가서 여기 Menu Bar Extra에 대한 새 Scene을 추가할 수 있어요 하지만 이것은 macOS 전용 기능이라 macOS SDK에 대해 조건화해야 합니다
이제 빌드하고 실행한 다음 살펴볼게요
아, 이제 제 트럭 아이콘이 메뉴 표시줄에 보이네요 멋지군요, 이제 제 Mac 사용자는 메뉴 표시줄에서 바로 오늘의 정보를 빠르게 볼 수 있어요 SwiftUI를 사용하면 각 플랫폼의 전체 SDK에 액세스하여 멋진 기능을 활용할 수 있어요 앱을 다른 플랫폼으로 가져올 때 우리는 새로운 플랫폼의 맥락에서 작업하는 경우 종종 과거의 많은 선택을 재고해야 할 때가 있어요 SwiftUI는 플랫폼 기대치를 API에 직접 적용하고 많은 인터페이스 요소가 각 플랫폼에서 자동으로 멋지게 보이게 됩니다 반대로, 컨트롤과 UI의 다른 부분을 지나치게 사용자 지정할 때 자동 스타일 지정을 잃을 수 있으니 항상 UI가 모든 곳에서 멋지게 보이는지 다시 확인해야 해요 즉, 멋진 앱을 구성할 때 Human Interface Guidelines에 명시된 모범 사례를 따르고 있는지 확인해봐야 해요 이제 앱에 대한 로컬 변경 사항에 만족하므로 앱 제품을 보관하고 App Store Connect에 업로드할 때가 왔습니다 이 작업은 Xcode에서 수행하거나 Xcode Cloud로 자동화할 수 있어요 준비가 되면 TestFlight의 내부 및 외부 테스터와 앱을 공유하고 App Store에서 출시할 수 있어요 App Store Connect에 업로드하려면 제품을 아카이브 해야 하는데요 단일 대상이 있다고 해서 단일 제품만 있는 것은 아니니까요 각 플랫폼에 대해 아카이브하고 개별적으로 업로드해야 해요 로컬에서 구축 및 아카이브 하는 경우 아카이브를 생성할 SDK가 있는 대상을 선택해야 합니다 제 macOS 앱을 제작하려면 대상 목록에서 'My Mac'을 선택해야 하는데 그렇지 않으면 iOS 기기를 선택하여 iOS 앱을 제작해야 하죠
대상을 선택했으면 'Product Archive'를 선택하여 아카이브를 생성할 수 있어요
아카이브가 완료되면 Xcode의 Organizer 창을 사용하여 App Store Connect에 업로드할 수 있어요
Xcode Cloud를 사용하는 경우 워크플로에 작업을 추가하여 제품을 빌드, 테스트 및 아카이브할 수 있고 제 워크플로의 작업 목록에서 새 항목을 만들어 각 제품을 빌드, 테스트, 분석 그리고 아카이브할 수도 있죠 이 경우 iOS 앱과 macOS 앱이 있는데 한 단계 더 나아가 제 앱을 App Store Connect에 자동으로 업로드하기 위한 배포 준비도 포함되며 이러한 빌드를 내부 TestFlight 팀에 즉시 보내고 뜨거운 변화에 대한 언론의 피드백을 받기 시작할 수도 있어요 요약하자면 Xcode 14는 이제 여러 플랫폼에서 더 많은 대상을 지원 가능한 간소화된 앱 타깃을 통해 다중 플랫폼 앱 개발을 한 단계 더 발전시킨 거라 할 수 있어요 단일 앱 대상으로 기본적으로 공통 코드베이스 그리고 공유 설정을 유지할 수 있죠 시연된 것처럼 필요에 따라 설정과 코드를 조건부로 지정하여 플랫폼 기대치에 가장 잘 맞도록 앱을 사용자 지정할 수도 있어요 나머지는 모두 여러분에 달려있어요 올해 Xcode의 새로운 기능과 개선 사항에 대해 자세히 알아보려면 'Xcode의 새로운 기능'을 확인해 보세요 Xcode와 SwiftUI의 힘으로 여러분이 어떤 놀라운 아이디어를 실현할 수 있게 될지 너무 기대되는군요
-
-
8:48 - canImport
#if canImport(ARKit) import ARKit #endif
-
10:02 - Condition Property
#if os(iOS) @Environment(\.editMode) private var editMode #endif
-
10:13 - Condition View Modifier
#if os(iOS) .onChange(of: editMode?.wrappedValue) { newValue in if newValue?.isEditing == false { selection.removeAll() } } #endif
-
10:19 - Condition View
#if os(iOS) EditButton() #endif
-
11:48 - Computed Property
var thumnailSize: Double { #if os(iOS) return 120 #else return 80 #endif }
-
12:37 - Menu Bar Extra
#if os(macOS) MenuBarExtra { MiniTruckView(model: model) } label: { Label("Food Truck", systemImage: "box.truck") } .menuBarExtraStyle(.window) #endif
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.