안녕하세요. 오랜만에 기술(?)글을 작성하게 되었습니다.
우선 민소네님의 블로그를 참고하였고, 코드 역시 거의 비슷할 수 있습니다.
뭔가 매번 한 발 느린 것 같습니다만, 느려도 일단 시작은 해보는 걸로!
참고1: http://minsone.github.io/ios/mac/ios-framework-part-2-project-subproject-dependencies
참고2: http://minsone.github.io/ios/mac/ios-managing-color-image-storyboard-xib-from-resources-framework
2019년에 작성하셨던 글이지만, 저는 이제야 뒤늦게 모듈화의 중요성을 깨닫고, 공부하고 글을 올립니다.
tuist도 한 번 올려야겠어요.
메인 프로젝트 내부에 서브 프로젝트를 만들어서, 메인 프로젝트나 상위 프로젝트에서만 서브 프로젝트의 코드를 알 수 있도록 해보려고 합니다.
Build Phases -> Dependencies 를 이용하면 된다고 합니다.
기본 프로젝트를 하나 생성한 뒤에, New Group을 선택한뒤 그룹 이름을 Dependencies로 적어줍니다.
Dependencies로 선택된 상태에서 File -> New -> Project 혹은 command + shift + N을 누르셔도 됩니다.
Framework를 새로 만들게 되면 기본적으로 Dynamic Framework로 만들어집니다.
그 다음 Framework 선택
Product Name 설정을 해줍니다.
Add to: 는 메인 서브젝트
Group은 이전에 만들어두었던 Dependencies로 선택 후 Create
하게되면,
서브 프로젝트 생성 완료!!
메인 프로젝트의 General -> Frameworks, libaries, and Embedded Content에 Service.Framework 추가
Dynamic Framework가 많을 수록 로드하는 시간이 오래 걸리고, 메인 프로젝트에 Dynamic Framework를 많이 임베드하고 있어야한다고 합니다.
Dynamic Framework 프로젝트를 만들고, 이 프로젝트 안에 Static Framework를 만들게되면 Dynamic Library에 Static Library에 Executable file이 복사되기 때문에, 서브 프로젝트트는 많아 지더라도, 메인 프로젝트에서 가지는 Dynamic Framework는 적은 숫자로 유지할 수 있습니다.
Service -> Dependencies 의 Group을 생성해준 뒤, 위와 같이 Framework를 만들어 줍니다.
Dependencies를 잘 보고 선택해줍니다.
Service안에 있는 Denpendencies Group을 잘 선택하고, Create 하여 줍니다.
AppLogService(이하 서브프로젝트) 프로젝트 생성이 완료되었습니다.
서브프로젝트(AppLogService) 내에 BuildSettings -> Linking -> Mach-O Type을 Static Library로 변경해주세요.
Service 프로젝트에서 Build Phases -> Dependencies에서 서브프로젝트를 추가해줍니다.
이렇게요.
Service 프로젝트는 Dynamic Framework이고, AppLogService 프로젝트는 Static Framework으므로, Service가 빌드되면서 Service Dynamic Library에 AppLogService Static Library가 복사될 거에요.
코드를 작성해서 확인해봐요!
/**
AppLogService 내 Service.swift 파일 생성
*/
public class Service {
public init() {}
public func logging(text: String) {
print("Send Log : \(text)")
}
}
/**
Service 내 Service.swift 파일 생성
*/
import AppLogService
public class Service {
let appLogService: AppLogService.Service
init() {
self.appLogService = AppLogService.Service()
}
public func start() {
appLogService.logging(txt: "Start")
}
}
메인 프로젝트의 AppDelegate에서 다음과 같이 코드를 추가해주세요.
import UIKit
import Service
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Service().start()
return true
}
}
빌드 후 앱을 실행하게 되면 콘솔에 AppLogService 프로젝트에서 추가한 logging의 pirnt가 콘솔에 보일 거에요.
|| Send Log : Start
이렇게 보이게 됩니다.
민소네님의 글을 보면, Framework 폴더안에 Framework가 생성된 것을 볼 수 있는 데, 안보이더라구요.
메인 프로젝트만 Product로 나와있어서 해당 Product를 클릭하고, Pull Path를 얻을 수 있었어요.
주소를 들어가보면 다음과 같이 보여집니다.
위에서 생성했던 framework들이 다 있습니다.
터미널에서 확인을 한 번 해볼께요.
nm Service.framework/Service
0000000000002860 T _$s13AppLogService0C0C7logging3txtySS_tF
0000000000003ddc S _$s13AppLogService0C0C7logging3txtySS_tFTq
0000000000002750 T _$s13AppLogService0C0CACycfC
0000000000003dd4 S _$s13AppLogService0C0CACycfCTq
0000000000002840 T _$s13AppLogService0C0CACycfc
0000000000003f34 s _$s13AppLogService0C0CMF
00000000000031d0 T _$s13AppLogService0C0CMa
0000000000008328 d _$s13AppLogService0C0CMf
0000000000008300 D _$s13AppLogService0C0CMm
0000000000003da0 S _$s13AppLogService0C0CMn
0000000000008338 D _$s13AppLogService0C0CN
0000000000003190 T _$s13AppLogService0C0CfD
0000000000003170 T _$s13AppLogService0C0Cfd
0000000000003d8c s _$s13AppLogServiceMXM
00000000000025c0 T _$s7ServiceAAC06appLogA003AppcA0AACvg
0000000000003d10 S _$s7ServiceAAC06appLogA003AppcA0AACvpMV
0000000000003d18 S _$s7ServiceAAC06appLogA003AppcA0AACvpWvd
0000000000002650 T _$s7ServiceAAC5startyyF
0000000000003d70 S _$s7ServiceAAC5startyyFTq
00000000000025e0 T _$s7ServiceAACABycfC
0000000000003d68 S _$s7ServiceAACABycfCTq
0000000000002610 T _$s7ServiceAACABycfc
0000000000003f18 s _$s7ServiceAACMF
0000000000002730 T _$s7ServiceAACMa
0000000000008280 d _$s7ServiceAACMf
0000000000008258 D _$s7ServiceAACMm
0000000000003d34 S _$s7ServiceAACMn
0000000000008290 D _$s7ServiceAACN
00000000000026f0 T _$s7ServiceAACfD
00000000000026c0 T _$s7ServiceAACfd
0000000000003d28 s _$s7ServiceMXM
U _$sBoWV
U _$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
U _$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
U _$sSSN
U _$sSSs20TextOutputStreamablesWP
U _$sSSs23CustomStringConvertiblesWP
00000000000031f0 t _$sSa12_endMutationyyF
U _$sSaMa
U _$ss26DefaultStringInterpolationV06appendC0yyxs06CustomB11ConvertibleRzs20TextOutputStrea
......
이하 줄임
Service 라이브러리의 Symbol 목록을 확인하면 AppLogService의 코드가 있는 것을 확인할 수 있습니다.
AppLogService 라이브러리를 위와 같은 명령어로 확인해보겠습니다.
AppLogService.framework/AppLogService(AppLogService_vers.o):
0000000000000038 S _AppLogServiceVersionNumber
0000000000000000 S _AppLogServiceVersionString
AppLogService.framework/AppLogService(Service.o):
0000000000000050 T _$s13AppLogService0C0C7logging3txtySS_tF
0000000000000548 S _$s13AppLogService0C0C7logging3txtySS_tFTq
0000000000000000 T _$s13AppLogService0C0CACycfC
0000000000000540 S _$s13AppLogService0C0CACycfCTq
0000000000000030 T _$s13AppLogService0C0CACycfc
0000000000000558 s _$s13AppLogService0C0CMF
0000000000000360 T _$s13AppLogService0C0CMa
00000000000003e8 d _$s13AppLogService0C0CMf
00000000000003c0 D _$s13AppLogService0C0CMm
000000000000050c S _$s13AppLogService0C0CMn
00000000000003f8 D _$s13AppLogService0C0CN
0000000000000320 T _$s13AppLogService0C0CfD
0000000000000300 T _$s13AppLogService0C0Cfd
00000000000004f8 S _$s13AppLogServiceMXM
U _$sBoWV
U _$sSS19stringInterpolationSSs013DefaultStringB0V_tcfC
U _$sSS21_builtinStringLiteral17utf8CodeUnitCount7isASCIISSBp_BwBi1_tcfC
U _$sSSN
U _$sSSs20TextOutputStreamablesWP
U _$sSSs23CustomStringConvertiblesWP
0000000000000380 T _$sSa12_endMutationyyF
U _$sSaMa
U _$ss26DefaultStringInterpolationV06appendC0yyxs06CustomB11ConvertibleRzs20TextOutputStreamableRzlF
U _$ss26DefaultStringInterpolationV13appendLiteralyySSF
U _$ss26DefaultStringInterpolationV15literalCapacity18interpolationCountABSi_SitcfC
0000000000000260 T _$ss26DefaultStringInterpolationVWOh
U _$ss27_allocateUninitializedArrayySayxG_BptBwlF
0000000000000280 T _$ss27_finalizeUninitializedArrayySayxGABnlF
U _$ss5print_9separator10terminatoryypd_S2StF
00000000000002c0 T _$ss5print_9separator10terminatoryypd_S2StFfA0_
00000000000002e0 T _$ss5print_9separator10terminatoryypd_S2StFfA1_
U _$sypN
U _OBJC_CLASS_$__TtCs12_SwiftObject
U _OBJC_METACLASS_$__TtCs12_SwiftObject
........
이하 줄임
Static Linker가 AppLogService Static Library를 Service Dynamic Library에 복사되는 것을 확인할 수 있습니다.
추가적으로 테스트를 하셨지만, 추가적 테스트 하신 부분에 있어서는 공부를 조금 더 해야할 것 같습니다.
ViewController, 프로젝트에 사용되는 공통적인 Resources(컬러, 이미지) 등을 사용하거나, 기능별(커스텀한 바텀시트, 얼럿창)로 적절히 분배하여 사용하면 좋을 것 같습니다.
이해가 부족할 수 있지만, 이상하다 싶은 내용이라면 언제든지 배움 주세요!
감사합니다.
'Programming > Swift' 카테고리의 다른 글
tuist로 Clean Architecture 직접 설계 해서 만들어보기 (0) | 2023.07.17 |
---|---|
Storyboard, Color, Image 등 Resource framework에서 관리하기 (0) | 2022.03.07 |
[iOS] Your enrollment could not be completed (4) | 2020.09.18 |
[Swift] Touch-id, Face-id를 적용해봐요. (0) | 2020.09.04 |
[Swift] iOS Push Image도 받아보기(Feat.FCM) 2/2 (2) | 2020.09.01 |