스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
Swift 패키지 플러그인 소개
Swift 패키지 플러그인을 통해 Swift 패키지 및 Xcode 프로젝트에서 작업을 수행하는 방법을 확인하세요. 이러한 플러그인의 작동 원리에 대해 다루고, 이를 통해 소스 코드를 생성하고 개발 작업 흐름을 자동화하는 방법을 살펴보겠습니다.
리소스
관련 비디오
WWDC23
WWDC22
WWDC19
-
다운로드
♪ 부드러운 힙합 반주 ♪ ♪ 안녕하세요 전 Anders합니다 이 동영상에선 Swift 패키지 플러그인 시작법을 알려드리죠 Xcode 11에 소개된 Swift 패키지는 라이브러리를 소스 코드로 잘 배포합니다 Xcode 14는 이 방식을 개발 워크플로로 확장해 플러그인으로 작업해서 빌드 중에 소스 코드를 생성하고 작업 배포를 자동화할 수 있죠 패키지 플러그인이 뭐고 어떻게 작동하는지 살펴본 후 Xcode 14가 지원하는 두 가지 패키지 플러그인을 상세히 다뤄 보겠습니다 명령 플러그인과 빌드 도구 플러그인입니다 그러면 우선 플러그인이란 뭘까요? 패키지 플러그인은 Swift 스크립트로 Swift 패키지나 Xcode 프로젝트를 실행합니다 Xcode가 이 목적을 위해 특별히 제공하는 API를 쓰는 플러그인이죠 패키지 플러그인은 Swift 패키지로 실행됩니다 플러그인과 더불어 라이브러리와 실행 파일을 제공하죠 이 패키지로 플러그인 제공에만 중점을 둘 수도 있죠 하나 이상의 소스 파일로 패키지 플러그인을 실행할 수 있고 하나 이상의 플러그인으로 Swift 패키지를 정의하죠 고도로 특수한 플러그인으로 제공하는 패키지를 비공개화할 수 있고 그럴 경우엔 그 패키지 안에서만 쓸 수 있습니다 하지만 패키지 상품으로 정의하면 다른 패키지에서도 범용 플러그인으로 쓸 수 있죠 그렇게 다른 패키지에서도 사용하고 다른 패키지 라이브러리를 사용하는 방법과 비슷한 점이 있습니다 하지만 라이브러리와 달리 플러그인에 종속돼 앱에 런타임 콘텐츠를 불러올 순 없죠 그 대신 본인 기기에서 실행하거나 빌드 자동화 중인 개발 도구에 접속할 수 있는데 이 패키지 플러그인으로 뭘 할까요? Xcode 14엔 두 가지 패키지 플러그인이 있죠 명령 플러그인과 빌드 도구 플러그인입니다 명령 플러그인은 지정한 작업을 실행하며 언제든 원할 때 작동시킬 수 있죠 소스 코드 포매터나 린터를 실행하거나 개발 워크플로의 일환으로 다른 작업도 할 수 있습니다 기여자 목록이나 Git 히스토리 기반 소스 코드의 저작권 일자도 갱신됩니다 오늘 임의적인 스크립트로 하는 작업도 가능하죠 필요하면 명령 플러그인으로 패키지 파일의 변경 허가를 요청할 수 있습니다 특히 코드 포매팅에 유용한 방식이죠 명령 플러그인이라도 허가를 입력하지 않고 아무런 변화 없이 리포트를 만들거나 코드의 매트릭스를 산출할 수 있기도 합니다 빌드 시스템을 종속성 그래프로 확장하는 빌드 도구 플러그인은 특히 소스 코드나 빌드의 일부로서 리소스를 생성할 때 유용합니다 한 번에 패키지 전체나 프로젝트를 구동하는 명령 플러그인과 다르게 빌드 도구 플러그인은 필요한 대상에 적용됩니다 Xcode에서 명령 플러그인 사용법을 살펴보겠습니다 이건 iOS 앱으로 다양한 기하학적 형태를 보여 주는데 앱 프로젝트와 로컬 패키지로 구성되죠 패키지가 실행하는 라이브러리로 핵심 데이터 유형과 앱 논리를 제공합니다 다른 사람도 쓸 수 있게 패키지를 자체 저장소로 분할해 보겠습니다 그 과정에서 기여자 파일을 만들어 이 패키지 코딩에 반영하는 모두를 목록에 올리죠 지정 스크립트를 써서 할 수 있지만 이 코드 작업에 유용한 플러그인을 제공하는 패키지란 걸 아니 제가 원하는 대로 쓸 플러그인이 있겠죠 다른 패키지 라이브러리가 필요할 때와 같은 방식으로 이런 플러그인에 접속합니다 제 로컬 패키지 매니페스트에 패키지 종속성을 추가하겠습니다 매니페스트 저장시 Xcode가 원격 패키지를 불러 패키지 종속 구역에 나타납니다 제가 보니 Xcode가 Swift포맷도 부르는데 대중적인 코드 포매팅 도구입니다 Swift포맷에 차례차례 종속되는 명령 플러그인이 유틸리티 패키지에 있어서죠 이제 이런 종속성을 추가했으니 이 패키지가 제공하는 플러그인에 전부 다 접속됩니다 명령어를 적용하고 싶은 패키지의 컨텍스트 메뉴를 써 보겠습니다 메뉴에 새 명령어 세 개가 생겼습니다 하나는 Swift포캣을 쓰는 소스 코드 재포맷이고 나머지 둘은 특정 동작을 제공하죠 첫 번째는 Git 커밋 히스토리 기반의 기여자 파일을 생성하거나 업데이트하고 두 번째는 제 소스 파일의 저작권 일자를 갱신합니다 가운데 명령어는 제가 원하는 작업을 수행하죠 제 패키지의 플러그인 명령을 호출하면 Xcode가 플러그인에 넘길 대상을 선택하게 해 주죠 이 경우엔 패키지 전체를 호출할 겁니다 플러그인이 지정 인수를 받아들이면 제가 이쪽으로 옮길 수도 있습니다 Run을 클릭하면 파일 시스템을 플러그인이 변경하기 때문에 Xcode가 그 상황을 경고해 주죠 제 코드를 변경하고 싶은 이유를 플러그인 저자가 밝히는데 전 플러그인이 실행되는 것도 엿보고 싶습니다 그래서 명령 보기를 선택하면 Xcode가 코드로 안내합니다
이 플러그인은 안전하게 작동하죠 그러니 다시 명령어를 불러서 이번엔 Run을 선택할 겁니다
이 플러그인의 제 선택 사항을 Xcode에 기억하라고 합니다 이 플러그인은 Git 히스토리를 써서 기여자명이 나타나는 파일 목록을 생성합니다 하지만 명령 플러그인은 무척 탄력적으로 쓸 수 있죠 이젠 Xcode의 명령 플러그인으로 플러그인이 어떻게 작동하나 자세히 살펴보죠 패키지 플러그인은 Swift 스크립트로 필요할 때 컴파일돼서 작동합니다 플러그인은 각각 별개의 프로세스를 거치죠 플러그인은 소스 코드가 포함된 입력 패키지의 정제된 표현에 접속합니다 플러그인은 패키지의 종속성에 대한 정보도 다 입수합니다 작업 과정의 일환으로 명령줄 도구를 부르는 플러그인이 많죠 플러그인은 파일과 디렉터리도 생성하며 파운데이션 같은 표준 라이브러리로 다른 동작도 수행합니다 네트워크 접속을 막는 샌드박스 안에서 작동하니 파일 시스템에서 몇 군데서만 입력할 수 있죠 빌드 출력 디렉터리 같은 곳입니다 명령 플러그인은 권한을 요청해 패키지 소스 디렉터리의 파일도 변경할 수 있죠 사용자가 승인하면 이런 곳에서 입력하게끔 샌드박스가 설정됩니다 플러그인은 Xcode로 그 결과도 다시 보내며 경고와 에러를 표시하고 빌드 도구 플러그인이 도구 호출을 정의하면 Xcode가 빌드 중에 실행할 수 있습니다 패키지 플러그인은 다 Xcode가 제공하는 패키지플러그인 모듈의 API를 쓰죠 API가 플러그인의 입력 패키지 접속을 허가하고 적절한 경우 Xcode에 그 결과를 보냅니다 플러그인을 실행하는 주요 소스 파일이 주 진입점도 정의합니다 플러그인 유형과 일치하는 프로토콜에 따르는 클래스나 구조체라야죠 Xcode가 호출하는 이 진입점의 기능은 플러그인의 유형에 좌우됩니다 'Swift 패키지 플러그인 만들기' 영상에서 패키지플러그인 API를 더 배우실 수 있죠 앞서 명령 플러그인을 써서 우리 패키지를 바꿔 봤는데 명령 플러그인의 세부 사항을 좀 더 살펴보죠 명령 플러그인은 개발 워크플로를 확장합니다 각각의 패키지에 직접 적용되며 빌드 중엔 안 됩니다 명령 플러그인이 다 파일 시스템을 변경하진 않죠 파일을 바꾸지 않는 유용한 기능도 있습니다 하지만 파일 시스템에 입력하지 않으려면 플러그인을 실행하는 패키지 매니페스트에 선언해야만 합니다 이러면 Xcode가 플러그인 가동 전에 사용자에게 허가를 요청하죠 보통 플러그인은 무척 작고 실제로 작업할 때 다른 도구에 의존하기도 하죠 앞서 모든 실제 작업에 Swift포맷을 쓰는 플러그인을 봤습니다 도구 패키지 종속성은 2진법이나 소스 코드에 따르죠 Xcode는 명령 호출 전에 소스에서 필요한 도구를 다 만들 수 있습니다 의존하는 도구 말고 다른 패키지에서 플러그인을 제공받을 수도 있죠 명령 플러그인을 실행할 때 주요 유형은 명령플러그인 프로토콜에 따르며 플러그인은 명령 수행 진입점을 실행합니다 이 진입점은 사용자가 제공하는 컨텍스트와 지정 인수를 다 받아들이죠 명령 플러그인을 부르는 다른 방법도 살펴보죠 아까와 같은 프로젝트를 써 보겠습니다 소스코드유틸리티 패키지에 아까 제가 종속성을 추가해서 터미널에 같은 플러그인을 부를 수 있죠 우선 CoreLibs의 디렉터리를 바꾸죠 제가 명령 플러그인을 적용하고 싶은 패키지니까요 Swift Package Manager 5.6엔 플러그인의 새 부명령이 있죠 'swift 패키지 플러그인 리스트'를 입력해 어떤 플러그인을 쓸 수 있나 보죠 Xcode의 메뉴와 같은 플러그인이 나옵니다 이 명령줄에서 각각의 명령을 보면 실행하려면 써야 할 동사가 있습니다 제가 Xcode에서 했던 기여자 목록을 재생하는 동사를 써 보겠습니다 플러그인이 파일 시스템 입력 권한을 요청하죠 파일을 생성하게요 '예스'를 입력해 허가하면 플러그인이 기여자 목록을 실행해 업데이트할 수 있죠 이런 요청 없이 플러그인이 파일 시스템에 입력하는 패키지 매니저 옵션을 쓸 수도 있습니다 CI 시스템이나 다른 빌드 자동화 중에 호출할 경우 특히 유용한 방법입니다 하지만 이 옵션을 쓰기 전에 플러그인이 뭘 하고 있나 확인해야죠 Xcode처럼 명령줄 인수를 플러그인에 보낼 수 있죠 플러그인 동작 동사 다음의 인수는 다 플러그인으로 보내집니다 이 경우엔 자세한 플래그를 써서 실행 플러그인의 출력에 대해 더 살펴보죠 명령 플러그인마다 지원하는 인수를 정의합니다 지금까지 주로 명령 플러그인을 다뤄 봤지만 빌드 도구 플러그인에 대해 할 얘기가 더 남았죠 명령 플러그인과 달리 빌드 도구 플러그인은 즉시 작업을 실행하지 않죠 그 대신 패키지를 만들면 Xcode가 실행할 빌드 도구 호출을 생성하고 돌려보냅니다 이 도구 호출마다 실행할 명령줄이 있으며 입출력 기능도 있어서 언제 실행할지 Xcode에 알려 줍니다 빌드 중이나 전후에 실행할 명령을 빌드 도구 플러그인으로 정의할 수 있죠 잠시 후 그 차이점을 살펴보겠습니다
보통 빌드 도구 플러그인이 돌려보낸 명령 설정으로 빌드 디렉터리에 출력을 입력하니 증분 빌드 사이에 계속 남아 있습니다 플러그인 자체와 마찬가지로 빌드 도구 플러그인이 정의한 명령이 네트워크 접속과 패키지의 변경을 다 차단하는 샌드박스 안에서 실행됩니다 빌드 도구 플러그인을 실행할 때 주요 유형은 빌드도구플러그인 프로토콜에 따르며 플러그인은 빌드 명령을 만들 진입점을 실행하죠 이 진입점은 빌드 명령을 만들 컨텍스트와 대상을 받아들입니다 지정 빌드 명령을 돌려보내면 패키지를 만들 때 실행됩니다 기본적인 빌드 명령 종류는 두 가지로 빌드 도구 플러그인이 돌려보낼 수 있죠 보통 빌드 명령은 입출력 경로를 명시하며 출력이 사라질 때나 입력이 변경될 때만 실행됩니다 사전 빌드 명령은 빌드 시작 전에 실행되며 미리 출력명을 모를 때 사용할 수 있습니다 빌드 전마다 사전 빌드 명령이 실행돼 변화가 없을 경우 최대한 작업을 줄입니다 빌드 명령과 사전 빌드 명령은 소스 코드나 리소스 생성에 유용합니다 Xcode가 어떤 빌드 도구 플러그인을 패키지 대상에 적용할지 어떻게 알까요? SwiftPM 5.6과 그 이후엔 패키지 매니페스트에 새 매개 변수가 생겼죠 대상이 요구하는 빌드 도구 플러그인 목록이 있어서 대상에 필요한 빌드 도구 플러그인이 매개 변수에 명시됩니다 종속된 모든 런타임 라이브러리와 함께 같은 패키지나 다른 패키지에 이런 플러그인이 있을 수 있죠 Xcode로 돌아가서 빌드 도구 플러그인을 써서 기하학 앱을 설정하겠습니다 이 경우엔 Core Library 대상의 데이터 파일 기반으로 Swift 코드를 생성하는 지정 명령줄이 있죠 세부 사항은 중요치 않죠 하지만 데이터마다 안전한 유형의 Swift 접근자를 생성해 마무리하고 싶습니다 제 데이터 파일에 더해 전 지정 도구로 제 저장소에서 확인할 소스 코드를 생성했죠 수동으로 이 도구를 실행하며 Swift 래퍼 코드를 생성해 변화에 반영했습니다 제 데이터 파일이 바뀔 때마다요 빌드 도구 플러그인은 그 이상도 가능하죠 빌드 중에 코드를 생성해도 제 저장소에 생성된 코드를 계속 놔두지 않아도 됩니다
플러그인에 접속하고자 패키지 매니페스트로 가서 제가 쓰고 싶은 소스 생성 플러그인이 제공하는 패키지에 종속성을 추가합니다
제 패키지 대상이 저 패키지에서 정의한 빌드 도구 플러그인에 다 접속하게 됐죠
이젠 플러그인을 써야 할 대상에 가서 플러그인 매개 변수를 정의에 추가합니다
이려면 저 패키지의 빌드 도구를 제 대상에 적용하고 싶다고 Xcode에 알려 주죠 이젠 제 저장소에 생성된 소스 파일을 삭제할 수 있습니다 빌드 중에 필요하면 생성되거나 업데이트될 겁니다
자, 훨씬 더 깔끔해졌습니다 이젠 제 앱을 만들거나 실행할 때 제 빌드 도구 플러그인이 제 데이터 파일이 바뀔 때마다 Xcode에 코드 생성 도구를 부르라고 알려 주죠 제 빌드 폴더에 다른 필드 파일과 함께 생성된 코드가 저장되면 제 저장소가 깔끔해집니다 이 영상에선 Swift 패키지가 어떤 것이고 어떻게 작동하는지 다뤄 봤습니다 명령 플러그인과 빌드 도구 플러그인의 비슷한 점과 차이점에 대해서도 얘기했고요 여러분 패키지에서 무작위 스크립트를 더 체계적으로 확장하게끔 대체할 수 있는 두 가지 플러그인이죠 빌드 도구 플러그인으로 빌드 시스템을 확장해 소스와 리소스를 생성할 수 있습니다 빌드의 일환으로 다른 지정 작업도 가능하죠 명령 플러그인은 지정된 동작으로 일반 개발 업무를 자동화하게 해 줍니다 특정한 워크플로에 맞추거나 다양한 경우에 유용하게끔 입력할 수도 있습니다 패키지 플러그인을 직접 만드시려면 잊지 말고 'Swift 패키지 플러그인 만들기' 영상을 참고하세요 감사합니다, WWDC 2022를 계속 즐겨 주세요 ♪"WWDC22"
-
-
import PackagePlugin @main struct MyPlugin: ... { // Entry points specific to plugin capability. These entry points are invoked // when the plugin is applied to a package. } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: ... { // Entry points specific to plugin capability. These entry points are invoked // when the plugin is applied to an Xcdeo project. } #endif
-
8:33 - Structure of a command plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin @main struct MyPlugin: CommandPlugin { /// This entry point is called when operating on a Swift package. func performCommand(context: PluginContext, arguments: [String]) throws { debugPrint(context) } } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: XcodeCommandPlugin { /// This entry point is called when operating on an Xcode project. func performCommand(context: XcodePluginContext, arguments: [String]) throws { debugPrint(context) } } #endif
-
11:13 - Structure of a build tool plugin with conditional support for Xcode projects when running in Xcode
import PackagePlugin @main struct MyPlugin: BuildToolPlugin { /// This entry point is called when operating on a Swift package. func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] debugPrint(context) return [] } } #if canImport(XcodeProjectPlugin) import XcodeProjectPlugin extension MyPlugin: XcodeBuildToolPlugin { /// This entry point is called when operating on an Xcode project. func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] debugPrint(context) return [] } } #endif
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.