Skip to content

Commit 84d52ea

Browse files
committed
add draft
1 parent af6b880 commit 84d52ea

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
layout: post
3+
title: "[Swift 5.9+][SE-0386] 새로운 Access Modifier인 Package를 Xcode Project에서 사용하기"
4+
tags: [access modifier, package, xcode, swift]
5+
published: false
6+
---
7+
{% include JB/setup %}
8+
9+
Swift 5.9에서 Swift Package에 새로운 접근 제어자 `Package`가 추가되었습니다. [SE-0386](https://github.com/apple/swift-evolution/blob/main/proposals/0386-package-access-modifier.md)
10+
11+
`Package` 접근 제어자는 특정 도메인이나 특정 역할을 가진 모듈에서만 접근할 수 있게 해줄 수 있어, 유용하게 사용될 것으로 생각됩니다.
12+
13+
그러나 Swift Package가 아닌 Xcode Project로 구축된 프로젝트라면, 새롭게 추가된 접근 제어자인 `Package`를 사용할 수 없어 아쉬울 수 밖에 없습니다.
14+
15+
만약, Xcode Project로 구축된 프로젝트에서 `Package` 접근 제어자를 사용할 수 있다면 어떨까요?
16+
17+
## SE-0386
18+
19+
SE-0386 제안서에서 패키지의 경계를 정의하는 것을 빌드 시스템에 의존하도록 하여, `-package-name` 플래그에 패키지명을 전달하도록 합니다.
20+
21+
즉, Swift Package는 해당 옵션을 빌드 시스템에 전달하여, `Package` 접근 제어자를 사용할 수 있게 합니다.
22+
23+
간단한 Swift Package를 만들고, Package.swift에 `packageAccess` 옵션을 추가한 뒤, 빌드하여 `-package-name` 플래그를 전달하는지 확인해봅시다.
24+
25+
```swift
26+
// Package.swift
27+
import PackageDescription
28+
29+
let package = Package(
30+
name: "MyLibrary",
31+
products: [
32+
.library(
33+
name: "MyLibrary",
34+
targets: ["MyLibrary"]),
35+
],
36+
targets: [
37+
.target(
38+
name: "MyLibrary",
39+
packageAccess: true),
40+
]
41+
)
42+
```
43+
44+
```
45+
$ swift build --verbose
46+
Planning build
47+
Building for debugging...
48+
Write auxiliary file /MyLibrary/.build/arm64-apple-macosx/debug/swift-version-4987FB7F52197B0.txt
49+
/Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MyLibrary -emit-dependencies -emit-module -emit-module-path /MyLibrary/.build/arm64-apple-macosx/debug/MyLibrary.swiftmodule -output-file-map /MyLibrary/.build/arm64-apple-macosx/debug/MyLibrary.build/output-file-map.json -parse-as-library -incremental -c @/MyLibrary/.build/arm64-apple-macosx/debug/MyLibrary.build/sources -I /MyLibrary/.build/arm64-apple-macosx/debug -target arm64-apple-macosx10.13 -swift-version 5 -v -enable-batch-mode -index-store-path /MyLibrary/.build/arm64-apple-macosx/debug/index/store -Onone -enable-testing -j8 -DSWIFT_PACKAGE -DDEBUG -module-cache-path /MyLibrary/.build/arm64-apple-macosx/debug/ModuleCache -parseable-output -parse-as-library -emit-objc-header -emit-objc-header-path /MyLibrary/.build/arm64-apple-macosx/debug/MyLibrary.build/MyLibrary-Swift.h -color-diagnostics -sdk /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -F /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -I /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -L /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -g -Xcc -isysroot -Xcc /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -Xcc -F -Xcc /Applications/Xcode-15.3.0-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -Xcc -fPIC -Xcc -g -package-name mylibrary
50+
Apple Swift version 5.10 (swiftlang-5.10.0.10.5 clang-1500.3.7.4)
51+
Target: arm64-apple-macosx10.13
52+
Build complete! (0.20s)
53+
```
54+
55+
로그를 확인해보니, `-package-name mylibrary` 옵션을 전달하는 것을 확인할 수 있었습니다.
56+
57+
그러면, Xcode Project에서도 `Package` 접근 제어자를 사용할 수 있을까요?
58+
59+
## Xcode Project
60+
61+
다음과 같은 의존관계를 가지는 프로젝트를 구축합니다.
62+
63+
<div class="mermaid" style="display:flex;justify-content:center;">
64+
graph TD;
65+
Application-->FeatureA-->FeatureB;
66+
</div>
67+
68+
<!-- 이미지1 -->
69+
70+
FeatureA의 Package Name은 Alpha, FeatureB의 Package Name은 Beta 라고 설정할 것입니다.
71+
72+
각 모듈의 Package Name을 설정하기 위해, Build Settings에서 `OTHER_SWIFT_FLAGS``-package-name` 옵션을 추가합니다.
73+
74+
<!-- 이미지2 -->
75+
76+
```
77+
// FeatureA
78+
OTHER_SWIFT_FLAGS = $(inherited) -package-name Alpha
79+
80+
// FeatureB
81+
OTHER_SWIFT_FLAGS = $(inherited) -package-name Beta
82+
```
83+
84+
FeatureA에는 SampleAlpha라는 클래스가 있고, FeatureB에는 SampleBeta라는 클래스를 만들고, 각 클래스에 접근 제어자를 `package`로 적용합니다.
85+
86+
```swift
87+
// Module: FeatureA
88+
// FileName: SampleAlpha.swift
89+
90+
import Foundation
91+
92+
package class SampleAlpha {
93+
package init() {
94+
print("init \(Self.self)")
95+
}
96+
97+
package func sampleFunc() {
98+
print("call \(#function)")
99+
}
100+
}
101+
102+
103+
// Module: FeatureB
104+
// FileName: SampleBeta.swift
105+
106+
import Foundation
107+
108+
package class SampleBeta {
109+
package init() {
110+
print("init \(Self.self)")
111+
}
112+
113+
package func sampleFunc() {
114+
print("call \(#function)")
115+
}
116+
}
117+
```
118+
119+
Application은 아직 Package Name을 설정하지 않았기 때문에, `SampleAlpha``SampleBeta` 클래스를 접근할 수 없습니다.
120+
121+
<!-- 이미지3 -->
122+
123+
Application의 Package Name을 `Beta`로 설정하도록 Build Settings에 `OTHER_SWIFT_FLAGS``-package-name Beta`를 설정합니다.
124+
125+
```
126+
// Application
127+
OTHER_SWIFT_FLAGS = $(inherited) -package-name Beta
128+
```
129+
130+
그러면 `SampleBeta` 클래스는 접근할 수 있지만, `SampleAlpha` 클래스는 접근할 수 없습니다.
131+
132+
<!-- 이미지4 -->
133+
134+
Application의 Package Name을 `Alpha`로 설정한다면, `SampleAlpha` 클래스를 접근할 수 있지만, `SampleBeta` 클래스는 접근할 수 없습니다.
135+
136+
<!-- 이미지5 -->
137+
138+
## 정리
139+
140+
* Package 접근 제어자는

0 commit comments

Comments
 (0)