Let’Swift 2023
Swift macro, 어디다 쓰죠?
김성종 (CJ올리브영)
들어가기 전에
들어가기 전에
Source of truth
들어가기 전에
Source of truth
목차
• 스위프트 매크로가 하는 일
목차
• 스위프트 매크로가 하는 일
목차
• 스위프트 매크로의 사용법
• 스위프트 매크로가 하는 일
목차
• 스위프트 매크로의 사용법
• 스위프트 매크로의 작성법
• 스위프트 매크로가 하는 일
목차
• 스위프트 매크로의 사용법
• 스위프트 매크로의 작성법
• 스위프트 매크로의 사용 예시
스위프트 매크로가 하는 일
비교대상 #1 - Code Snippet Library
비교대상 #1 - Code Snippet Library
비교대상 #1 - Code Snippet Library
Cmd + Shift + L
비교대상 #1 - Code Snippet Library
비교대상 #1 - Code Snippet Library
비교대상 #1 - Code Snippet Library
비교대상 #1 - Code Snippet Library
- 외부에 미리 만들어 둔 텍스트를 그대로 에디터에 붙여줍니다
- 코드 플레이스 홀더 작성 가능
- 라이브러리 패널 / 단축키로 빠르게 호출 가능
비교대상 #1 - Code Snippet Library
- 외부에 미리 만들어 둔 텍스트를 그대로 에디터에 붙여줍니다
- 코드 플레이스 홀더 작성 가능
- 라이브러리 패널 / 단축키로 빠르게 호출 가능
- 개발자가 직접 불러서 사용해야함. (백날 만들어 놔도…)
- 팀 내부에서 공유하기 번거로움
- 특정 위치에 스니펫 파일들을 설치하는 형식, 설치 스크립트 돌려야 해요
- 한번 설치된 파일 업데이트는 더 번거로움
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
😺
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
😾
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
비교대상 #2 - C Macro
🙀
비교대상 #2 - C Macro
비교대상 #2 - C Macro
- 프로젝트 내부에 정의한 텍스트를 전처리기가 그대로 붙여 넣어줍니다
- 텍스트 취급이라서 호출도 마음대로 사용 가능
비교대상 #2 - C Macro
- 프로젝트 내부에 정의한 텍스트를 전처리기가 그대로 붙여 넣어줍니다
- 텍스트 취급이라서 호출도 마음대로 사용 가능
- 멀티라인 정의
- 소스 파악할 때 위 아래로 오르락 내리락
- 다른 프로젝트에 공유할때 소스카피
- 텍스트 취급, 로직 실수 발생이 너무 쉬움
스위프트 매크로가 하는 일
이미지 출처: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/
매크로가 작성된 곳에 코드를 붙여넣어 줍니다
스위프트 매크로가 하는 일
이미지 출처: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/
차이점 #1
이미지 출처: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/
매크로가 작성된 곳에 코드를 붙여넣어 줍니다
매크로가 작성된 곳에 컴파일러가 코드를 만들어서 붙여넣어 줍니다
차이점 #1
이미지 출처: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/macros/
차이점 #2
이미지 출처: https://www.timc.dev/posts/understanding-swift-packages/
차이점 #2
Swift Package Manager
이미지 출처: https://www.timc.dev/posts/understanding-swift-packages/
차이점 #2
Swift Package Manager
팀 내부에서 공유, 버전관리, 다른 프로젝트에서 재사용
이미지 출처: https://www.timc.dev/posts/understanding-swift-packages/
차이점 #3
매크로 호출부에서 펼쳐보기 가능
차이점 #3
매크로 호출부에서 펼쳐보기 가능
결과물 코드는 복사 + 붙여넣기도 가능
차이점 #3
스위프트 매크로는
스위프트 매크로는
- 컴파일러가 원하는 위치에 코드를 생성해서 붙여줍니다
- 스위프트 패키지를 이용하여 배포
- 만들어진 코드 미리보기, 복사 붙여넣기 가능
- 타입 추론 돌아감
스위프트 매크로는
- 컴파일러가 원하는 위치에 코드를 생성해서 붙여줍니다
- 스위프트 패키지를 이용하여 배포
- 만들어진 코드 미리보기, 복사 붙여넣기 가능
- 타입 추론 돌아감
- 배경지식이 필요함
- 사용할 때: 7가지 역할을 이해해야 함
- 작성할 때: Swift Syntax Tree가 생소함
스위프트 매크로의 사용 방법
사용방법
사용방법
매크로의 역할에 맞춰서 기호와 이름을 작성하여 호출
#{ 매크로 이름 } 혹은 @{ 매크로 이름 }
사용방법
매크로의 역할에 맞춰서 기호와 이름을 작성하여 호출
#{ 매크로 이름 } 혹은 @{ 매크로 이름 }
사용방법
매크로의 역할에 맞춰서 기호와 이름을 작성하여 호출
펼쳐보기
펼쳐보기
펼쳐보기
매크로 호출부 우클릭 -> expand macro 선택
7가지 역할들
이미지 출처: https://developer.apple.com/wwdc23/10167
7가지 역할들
이미지 출처: https://developer.apple.com/wwdc23/10167
7가지 역할들
이미지 출처: https://developer.apple.com/wwdc23/10167
7가지 역할들
이미지 출처: https://developer.apple.com/wwdc23/10167
예시 출처
예시 출처
https://github.com/apple/swift-syntax
예시 출처
https://github.com/apple/swift-syntax
@freestanding(expression)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@freestanding(expression)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@freestanding(expression)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@freestanding(declaration)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@freestanding(declaration)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@freestanding(declaration)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Expression
@attached(peer)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Peer
@attached(peer)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Peer
@attached(peer)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Peer
@attached(accessor)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/ComplexMacros
@attached(accessor)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/ComplexMacros
@attached(accessor)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/ComplexMacros
@attached(memberAttribute)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/MemberAttribute
@attached(memberAttribute)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/MemberAttribute
@attached(memberAttribute)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/MemberAttribute
@attached(member)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Member
@attached(member)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Member
@attached(member)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Member
@attached(conformance)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Extension
@attached(conformance)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Extension
@attached(conformance)
출처: https://github.com/apple/swift-syntax/tree/main/Examples/Sources/MacroExamples/Implementation/Extension
스위프트 매크로의 작성 방법
작성 시작
Xcode 15 > New > Swift Package > macro template
작성 시작
매크로 패키지 구조
매크로 패키지 구조
매크로 패키지 구조
선언
매크로 패키지 구조
선언
실행
매크로 패키지 구조
선언
실행
구현
매크로 패키지 구조
선언
실행
구현
테스트
선언 타겟
선언 타겟
선언 타겟
매크로 선언에서 매크로를 호출합니다
실행 타겟
실행 타겟
구현 타겟
구현 타겟
구현 타겟
코드젠 프로그램의 시작점
구현타겟: Swift Syntax Tree
구현타겟: Swift Syntax Tree
구현 타겟에 브레이크 포인트 설정
테스트 코드 실행
po { 원하는 대상 }
구현타겟: Swift Syntax Tree
구현 타겟에 브레이크 포인트 설정
테스트 코드 실행
po { 원하는 대상 }
https://swift-ast-explorer.com/
구현타겟: AST 추가 도구
https://swift-ast-explorer.com/
구현타겟: AST 추가 도구
구현타겟: Diagnostic
구현타겟: Diagnostic
친절한 경고 메시지와 Fix-it 까지 제공 가능
구현타겟: Diagnostic
구현타겟: Diagnostic
https://github.com/apple/swift-syntax
구현타겟: Diagnostic
https://github.com/apple/swift-syntax
테스트 타겟
테스트 타겟
테스트 타겟
테스트 대상
테스트 타겟
테스트 대상
예측 결과
테스트 타겟
테스트 매크로 제공
테스트 대상
예측 결과
테스트 타겟: 추가 도구
https://github.com/pointfreeco/swift-macro-testing
테스트 타겟: 추가 도구
https://github.com/pointfreeco/swift-macro-testing
스위프트 매크로의 사용 예시
애플은 어디다 쓰나요
Xcode 15 SDK
애플은 어디다 쓰나요
Xcode 15 SDK
SwiftUI
- #Preview
애플은 어디다 쓰나요
Xcode 15 SDK
Observation
- @Observable
SwiftUI
- #Preview
애플은 어디다 쓰나요
Xcode 15 SDK
Observation
- @Observable
TipKit
- @Parameter
- #Rule
SwiftUI
- #Preview
애플은 어디다 쓰나요
Xcode 15 SDK
Observation
- @Observable
TipKit
- @Parameter
- #Rule
SwiftData
- @Transient
- @Attribute
- @Model
- @Query
- #Predicate
SwiftUI
- #Preview
애플은 어디다 쓰나요
커뮤니티는 어디다 쓰나요
커뮤니티는 어디다 쓰나요
Swift-Spyable
https://github.com/Matejkob/swift-spyable
https://swiftpackageindex.com/Matejkob/swift-spyable
우리는 어디다 해 볼 수 있을까요?
우리는 어디다 해 볼 수 있을까요?
팀 컨벤션이 있어서 어디서든 통용할 수 있는 매크로 만들기는 너무 힘듬
우리는 어디다 해 볼 수 있을까요?
팀 컨벤션이 있어서 어디서든 통용할 수 있는 매크로 만들기는 너무 힘듬
우리는 어디다 해 볼 수 있을까요?
팀 컨벤션이 있어서 어디서든 통용할 수 있는 매크로 만들기는 너무 힘듬
우리는 어디다 해 볼 수 있을까요?
팀 컨벤션이 있어서 어디서든 통용할 수 있는 매크로 만들기는 너무 힘듬
우리는 어디다 해 볼 수 있을까요?
우리는 어디다 해 볼 수 있을까요?
팀 내에 존재하는 애매한 중복 코드 제거
팀 안에서만 사용한다고 가정해보면 의외로 많음
우리는 어디다 해 볼 수 있을까요?
팀 내에 존재하는 애매한 중복 코드 제거
팀 안에서만 사용한다고 가정해보면 의외로 많음
예시를 하나 준비했습니다
요구사항 소개
요구사항 소개
Decodable을 채택한 자료형을 사용하기 불편한 경우
혹은 Codable 이전에 구현 된 프로젝트들
😿
요구사항 소개
Decodable을 채택한 자료형을 사용하기 불편한 경우
혹은 Codable 이전에 구현 된 프로젝트들
WKScriptMessage.body: Any -> JSONString -> Instance
XMLParser -> [String: Any] -> Instance
😿
😹
요구사항 소개
Decodable을 채택한 자료형을 사용하기 불편한 경우
혹은 Codable 이전에 구현 된 프로젝트들
WKScriptMessage.body: Any -> JSONString -> Instance
XMLParser -> [String: Any] -> Instance
Legacy Initializers
😿
😹
Heritage Initializers
요구사항 소개
Decodable을 채택한 자료형을 사용하기 불편한 경우
혹은 Codable 이전에 구현 된 프로젝트들
WKScriptMessage.body: Any -> JSONString -> Instance
XMLParser -> [String: Any] -> Instance
😿
😹
레포지토리
레포지토리
https://github.com/Willicious-k/HeritageInitializers
레포지토리
https://github.com/Willicious-k/HeritageInitializers
실행 결과
@InitFromDict
실행 결과
@InitFromDict
실행 결과
@InitFromDict
실행 결과
@InitFromJSONString
실행 결과
@InitFromJSONString
실행 결과
@InitFromJSONString
로직 설명: 조건 검사
로직 설명: 조건 검사
Struct, Class, Actor만 구분 하려면?
로직 설명: 조건 검사
Struct, Class, Actor만 구분 하려면?
🙏
로직 설명: 가드 조건문 만들기
로직 설명: 가드 조건문 만들기
로직 설명: 배정문 만들기
로직 설명: 배정문 만들기
로직 설명: 결과 블럭
로직 설명: 결과 블럭
로직 설명: 결과 블럭
String Interpolation을 잘 지원해서 엄청 어렵지는 않습니다
감사합니다 🙇
willicious.k@gmail.com
Let'Swift 2023 Swift Macro, 어디다 쓰죠?

Let'Swift 2023 Swift Macro, 어디다 쓰죠?