Programming/Swift

메인 프로젝트에 서브프로젝트 주입하기 - 01

ilovecoffee 2022. 3. 7. 12:53

안녕하세요. 오랜만에 기술(?)글을 작성하게 되었습니다.

 

우선 민소네님의 블로그를 참고하였고, 코드 역시 거의 비슷할 수 있습니다.

뭔가 매번 한 발 느린 것 같습니다만, 느려도 일단 시작은 해보는 걸로!

 

참고1: http://minsone.github.io/ios/mac/ios-framework-part-2-project-subproject-dependencies

 

[iOS][Xcode] Framework Part 2 : 프로젝트, 서브 프로젝트, Dependencies, 그리고 Static, Dynamic Framework

서론 프로젝트를 만들면 해당 프로젝트 내에 서브 프로젝트를 만드는 것에 이야기를 들어본적이 없었습니다. 프로젝트 하나에 모든 코드와 리소스가 다 들어가도록 개발을 했기 때문입니다. 하

minsone.github.io

참고2: http://minsone.github.io/ios/mac/ios-managing-color-image-storyboard-xib-from-resources-framework

 

[iOS][Xcode] Framework Part 3 : Storyboard, Xib, Color, Image를 리소스 프레임워크에서 관리

서론 각각의 기능으로 분리되어 있는 프로젝트들은 공통의 리소스를 가질 수 있습니다. 색상, 이미지, Lottie의 JSON 등을 말이죠. 각각의 프로젝트들은 공통의 리소스를 사용하여 개발해야 하기

minsone.github.io

 

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(컬러, 이미지) 등을 사용하거나, 기능별(커스텀한 바텀시트, 얼럿창)로 적절히 분배하여 사용하면 좋을 것 같습니다.

 

이해가 부족할 수 있지만, 이상하다 싶은 내용이라면 언제든지 배움 주세요! 

 

감사합니다.