Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- clean architecture
- Clean Code
- collectionview
- 애니메이션
- Observable
- ios
- uitableview
- UICollectionView
- RxCocoa
- combine
- Protocol
- map
- swift documentation
- rxswift
- tableView
- uiscrollview
- SWIFT
- 클린 코드
- ribs
- Refactoring
- 리펙토링
- swiftUI
- UITextView
- MVVM
- Xcode
- 리펙터링
- HIG
- 리팩토링
- 스위프트
- Human interface guide
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 5. WWDC2023 정리 - Swift 매크로 개념 (Swift Macro, SwiftSyntax, Swift 5.9) 본문
WWDC 정리/WWDC 2023 정리
[iOS - swift] 5. WWDC2023 정리 - Swift 매크로 개념 (Swift Macro, SwiftSyntax, Swift 5.9)
jake-kim 2023. 6. 10. 01:21Swift 매크로란?
- Swift 5.9에서 도입
- Swift 언어로 매크로를 쉽게 사용할 수 있는 것
- 매크로란? 매크로는 코드 조각을 정의하여 여러 곳에서 재사용할 수 있게 해주고 보통 전처리기에서 생성
- 전처리기란? 전처리기는 소스코드를 컴파일 하기 전 단계인 전처리 단계에서 수행해주는 것
- Swift 매크로가 있는 이유 - 컴파일 시간에 반복 코드를 생성할 수 있고 코드를 읽기 쉽게 만들 수 있음
ex) Swift 매크로를 이용하여 중복코드 단순화하기
- 예제 코드) 튜플 형태인 배열이 있는데 이 튜플에서 첫번째 값은 Int, 두번째 값은 String인 형태
- 중복코드형태이고 연산에 있어서 실수하기 쉬운 코드
- Swift5.9 에서 나오는 Swift 매크로를 사용하여 단순화한 형태
- 컴파일 타임에 정해지고, 중복코드가 많이 개선됨
매크로 사용 방법
- 매크로 정의
- 함수 형태와 유사하게 앞에 macro 키워드를 사용
- 매크로 표현식의 인수가 매크로의 매개변수와 일치하지 않거나 입력을 잘못하면 컴파일러는 매크로 확장을 적용하지 않고 오류를 발생
- 이 매크로를 이용하는 쪽에서는 #을 붙여서 사용
- 매크로 구현부는 매크로 플러그인에서 작성
매크로 플러그인
- 스위프트 매크로를 구현하는 부분
- 트리 - 노드 구조로 표현
- pound - 매크르롤 정의한다는 의미
- identifier("stringify") - 매크로의 이름
- leftParen, rightParen에서는 각 매크로의 동작을 표현
- 스위프트 매크로의 가장 좋은점?
- macro 구현 자체가 Swift로 작성된 프로그램이며 원하는 구문 트리로의 변환을 수행 가능
코드로 보는 매크로 구현 방법
- Xcode > New file > Swift Macro 선택
- WWDC라는 이름의 Swift Macro를 생성하면 템플릿 코드와 함께 생성
- 코드상에서 매크로의 구현이 어떻게 되어있는지 확인하기도 매우 용이
- Expand Macro 선택
(Expand Macro 선택 시 구현부가 노출)
- Swift Macro는 deterministic 트리 형태로 되어있기 때문에 테스트하기도 매우 용이
- Swift Macro 테스트 방법은 WWDC2023 09:10 참고
Macro의 종류
- 매크로 선언 시 property wrapper로 사용되는 종류는 아래와 같이 여러개가 존재
ex) @attached(member): 연결된 유형의 새 member를 추가하는 것
Swift Macro로 중복 코드 단순화하기
ex) 기울기 값을 가지는 Slope모델과, 낮은 기울기 값을 가지는 EasySlope 모델이 있는 상태
- 참고) Swift Macro를 정의할때 문자열로 정의해주는 부분이 있어서 테스트 코드와 함께 작성하는것을 추천 (아래 예제에서는 편의를 위해 테스트 코드는 작성 x)
- EasySlope에서는 Slope를 받아서 초기화하는 부분이 있고 이 안에는 slope라는 computed property가 있는데, 초기화 하는 부분과 slope computed property안에 동일한 코드가 있어서 코드 중복이 있는 문제점이 존재
- Xcode > New file > Swift Macro 템플릿 생성
- macro 선언
- 구현부에서는 Slope안에 있는 Macro를 정의
- SlopeSubsetMacro는 위에서 있던 EasySlope 부분에 사용될것이므로, Slope안에 EasySlope이 있는 개념이므로 subset 용어를 사용
- 선언된 enum을 가져오기
- lldb를 통해 enumDecl 값을 출력해보면, 트리 - 노드 구조로 표현된 부분 확인이 가능
- 구문 트리 구조를 분석하기 위해서 Macro 실행중에 break point를 두고 lldb에서 node를 인쇄하여 코드를 작성할 것
- 위 트리-노드 구조를 보고 enum의 case들에 모두 접근
- InitializerDeclSyntax를 사용하여 init 구문을 만드는 매크로를 만들고, 위에서 얻은 elements를 for-loop돌면서 case 항목 표현식을 작성
- 핵심) InitializerDeclSyntax, SwiftExprSyntax, SwitchCaseSyntax에 모델의 구조를 String 형태로 넣으면서 만드는 것
- Syntax 관련 코드는 SwiftSyntax모듈을 import하여 사용
- 사용하는쪽)
- 위에서 만든 스위프트 매크로를 EasySlope모델에 적용하기 위해, @SlopeSubset으로 선언하면 컴파일 에러가 발생
- 매크로에서 이미 선언되었으므로 중복 코드라고 에러가 발생하는것
- EasySlope안에 있는 init을 삭제하면 완성
- @SlopeSubset 오른쪽 클릭 > expand macro를 클릭하면 어떻게 정의되어 있는지 한번에 확인도 가능
(해당 예제에서는 init만 적용하고, computed property인 slope에 매크로 적용하는 것은 생략)
위 예제에서 Swift Macro로 변경하기 요약
- Swift Macro 패키지로 쉽게 생성이 가능
- EasySlopes유형에서 반복적인 코드 작성 필요 없이 Type Safety함을 얻을 수 있음
- 구문 트리 구조를 분석하기 위해서 Macro 실행중에 break point를 두고 lldb에서 node를 인쇄하여 코드를 작성
- 분석한 결과를 토대로 SwiftSyntax모듈에서 제공해주는 매크로 형태로 작성
- (주의할점은 테스트 케이스를 작성하여 계속 체크해야함)
enumDecl 생성을 실패했을때 처리 추가
- enumDecl의 guard문안에 TODO 부분 처리
- SlopeSubsetError.onlyApplicableToEnum과 같이 특정 에러를 정의하고 이를 throw해주면 사용하는쪽에서 쉽게 파악이 가능
사용하는쪽) struct에 잘못 사용한 경우 - 위에서 throw로 던진 에러가 표출
* 참고
'WWDC 정리 > WWDC 2023 정리' 카테고리의 다른 글
Comments