나만의 공부 노트
SPM 본문
Package.swift에 대해 제대로 이해해보자
사용하는 방법은 어렵지 않으니 패스..
생성하는 법부터 바로 알아보자
참고 사이트 : https://tech.kakao.com/posts/521
Package 생성하기
File->New->Package(더 쉽게는 왼쪽 하단에 + 버튼으로 Package 추가) 또는 터미널에서 'swift package init'를 입력
위 사진을 보니 Package가 xcodeproj와 거의 대응되는 용도로 사용되는 듯함
Package 생성 템플릿을 보니 보통,
library나 command line/excutable을 만드는데에만 사용하는 것 같다.
xcodeproj는 생성할 수 있는 템플릿이 다양하다
-> Package는 xcodeproj보다 단순화하여 library만을 다루기 위해 만든 tool 같다.
Package 구성 요소
패키지는 다음과 같이 targets, products, dependencies 크게 3가지로 이루어져 있다.
역시나 xcodeproj와 비슷하다.
Package는 Target에 대한 표준 구조를 가진다. 위에 폴더 구조를 보게 되면, Sources 디렉터리에 타겟의 모든 파일이 위치하고, 각 타겟은 타겟 이름과 동일한 이름으로 하위 디렉터리에 위치함
Package 배포하기
git repository 최상단 디렉토리에 Package.swift가 있으면, 다른 곳에서 해당 SPM을 사용 가능
https://github.com/Alamofire/Alamofire 의 경우, xcodeproj, xcframework, gem, cocoapod 등 다 지원하는 듯
Resources
Xcode12부터 타겟에 리소스가 있을 경우 그 리소스들을 번들화를 해주어 해당 타겟에서 사용할 수 있도록 해주었습니다.
아래 파일들은 패키지를 빌드 한 결과물입니다. 이 중에 MyPackage_MyTarget.bundle은 컴파일러가 해당 타겟에 포함된 리소스들을 번들로 만들어준 결과물입니다.
target에 포함되어 있는 리소스는 [패키지명_타켓명].bundle 으로 만들어서 포함시켜주는 듯
타겟에 리소스가 있을 경우, 해당 리소스들을 manifest 파일에서 target의 resources 파라미터에 추가합니다. 아래와 같이 xcassets와 storyboard 파일은 manifest 파일에 추가하지 않아도 번들화를 해주고, png 파일이나 디렉터리는 명시적으로 추가되어야 번들화가 되는 것을 볼 수 있습니다.
타겟에서 리소스 번들에 접근할 때 SwiftPM은 Bundle.module이라는 accessor로 접근합니다.
// Swift
let image = UIImage(named: "Logo", in: Bundle.module)
// Objective-C
UIImage *image = [UIImage imageNamed:@"Logo" inBundle:SWIFTPM_MODULE_BUNDLE];
MyTarget.modulemap
modulemap 파일이 어떤 기능을 하는지 알아보기 전에 Clang module이라는 개념에 대해서 알아보겠습니다.
Clang Module
Clang은 Apple의 공식 c 컴파일러입니다. 예를 들어, Objective-C에서 다른 파일에 있는 코드를 사용하고 싶을 경우, C이기 때문에 #include나 #import를 사용할 수 있습니다. 이 동작 방식은 해당 문에 선언된 헤더 파일 전체를 단순히 지시자의 위치로 복사하는 방식으로 동작합니다. 이 방식은 헤더 파일의 선언이 많아질수록 빌드 속도에 영향을 주게 되어, 빌드 속도 개선을 위해 등장한 것이 Clang Module입니다.
Clang Module은 프레임워크 당 헤더를 한 번만 찾아서 파싱을 한 이후, 해당 정보를 디스크에 저장하여 캐시 된 상태로 재사용할 수 있도록 하였습니다. 그리고 @import 어노테이션을 사용하여 Objective-C에서 모듈 단위로 import를 할 수 있게 빌드 시간을 개선하였습니다.
Module Map
modulemap 파일은 Clang Module을 구성해 주는 파일로, 특정 헤더 파일의 집합을 module로 변환해 주는 방식을 나타냅니다.
아래 파일은 위의 빌드 로그에서 본 MyTarget.modulemap 파일입니다. 파일 내용을 보면, module로 MyTarget이 선언되어 있고 header는 MyTarget-Swift.h로 되어있습니다. 이 말은 즉, MyTarget 모듈은 MyTarget-Swift.h 헤더 파일로 구성이 되어있다는 의미입니다.
?????
이해가 안가서 내가 다시 정리하면서 써봄
ex. 프레임워크의 구조
- Header의 경우 Framework 생성시 설정한 언어가 Swift인지 Objective-C인지에 따라 그 결과물이 바뀝니다. Xcode는 Framework 빌드시 Swift를 위한 별도의 Header 파일(ExampleFramework-Swift.h)을 생성합니다. Objective-C 기반 Framework는 이 파일이 생성되지 않습니다.
- ExampleFramework.h은 기본적으로 public header를 관리합니다. Objective-C로 작성된 객체를 외부에서 접근하기 위해서는 관련 header를 public으로 전환해주어야 합니다. 즉, ExampleFramework.h에 관련 header 파일을 작성해야 합니다. Swift 객체의 경우 접근 제어자 룰에 따라 외부 Framework에서 사용 가능 여부가 결정됩니다.
- Swift는 module 단위로 소스코드를 관리합니다. 하나의 module은 import시 하나의 module이 됩니다. modulemap은 module과 header의 연결고리 역할을 하는 파일로, module에 포함되는 header가 무엇인지 정의하고, 어떤 implementation(.a, .dylib)가 module에 포함되는지를 알려주는 파일입니다. Xcode 빌드 설정에서 DEFINE_MODULES 옵션에 따라 해당 파일의 생성 여부가 결정됩니다.(default 설정은 true입니다.)
흠.. 문법이나 정확한 구조에 대해서 설명하는 글이 없네..
https://www.jaenung.net/tree/954?srsltid=AfmBOoo4wZ8XssY5lMK3X2_2OGsnMSdZiKSQvO6wspIDSGWbVTsG-g2e
Swift와 C/C++ 코드 연동하기
Swift와 C/C++의 연동은 현대 iOS 및 macOS 애플리케이션 개발에서 중요한 기술입니다. 이 두 언어를 결합함으로써 개발자들은 Swift의 현대적이고 안전한 문법과 C/C++의 성능 및 기존 라이브러리를 모
www.jaenung.net
트러블 슈팅
- Swift Package Manager의 특징 중의 하나는 C 계열과 Swift 파일을 하나의 타겟으로 사용하지 못한다는 점
- objc와 c 파일이 함께 있으면, .o 파일이 중복 생성되는 문제 -> duplicated symbol 문제 발생 -> ld_classic(중복되는 symbol이면 가장 첫번째 심볼을 사용하는 옵션)을 사용하여 해결할 수 있으나, 근본적인 해결은 아니라고 봄 -> .o 파일이 중복 생성되는 문제를 해결해야하는데 spm쪽에서 발생한 이슈라.. 수정 불가능
'정리 X > Swift' 카테고리의 다른 글
열거형에 관하여 (0) | 2021.02.14 |
---|---|
변수의 키워드에 관하여 (0) | 2021.02.05 |
프로토콜과 익스텐션에 관하여 (0) | 2021.02.05 |
이니셜라이저의 키워드에 관하여 (0) | 2021.02.05 |
클로저(메모리)에 관하여 (0) | 2021.02.05 |