관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - Swift] 2. Tuist로 모듈화하기 - 기본 개념 (Dynamic Framework, Static Framework, Mach-O, Embed & Sign, Do Not Embed) 본문

iOS 응용 (swift)

[iOS - Swift] 2. Tuist로 모듈화하기 - 기본 개념 (Dynamic Framework, Static Framework, Mach-O, Embed & Sign, Do Not Embed)

jake-kim 2022. 12. 29. 23:05

Tuist로 모듈화 최신 포스팅 글 목록 > https://ios-development.tistory.com/1303


1. Tuist로 모듈화하기 - 이미 존재하는 프로젝트에 적용 방법

2. Tuist로 모듈화하기 - 기본 개념 (Dynamic Framework, Static Framework, Mach-O, Embed & Sign) <

3. Tuist로 모듈화하기 - Tuist로 프로젝트 구성 방법 (의존성 관리, 프로젝트 구조 설정)

Dynamic Framework, Static Framework 개념

  • Framework와 Library
    • Framework는 라이브러를 포함하는 하나의 패키지로 캡슐화한 디렉토리를 의미
    • Framework = Library + Nib + Resource (image, strings, header.. 등)
  • Dynamic Framework와 Static Framework
    • Dynamic Framework: 컴파일된 바이너리 파일이 Stack의 Bundle영역에 존재하여, 어플리케이션 코드에서 스택 영역을 참조하여 사용 (메모리 효율, 동적으로 연결되므로 전체 빌드를 다시 하지 않아도 프레임워크 사용 가능)
    • Static Framework: 컴파일된 바이너리 파일이, 앱의 실행 파일에 복사되어 바로 사용 (실행 파일에 포함하기 때문에 앱의 크기가 커지는 단점이 존재)
  • 사용처
    • Dynamic Framework -  리소스를 가지고 있거나 전체 소스를 제공하는 경우
    • Static Framework - 전체 소스를 제공하지 않고 SDK 형태로 배포하는 경우

Dynamic Framework 확인 방법

  • 예제로 사용할 프로젝트 준비 (Cocoapods으로 RxSwift 준비)

  • 빌드
    • 빌드하면 맥북 로컬에 프레임워크 정보가 저장(캐싱)

  • 위 RxSwift가 저장된 경로 확인
/Users/jake/Library/Developer/Xcode/DerivedData/ExApp-bwhvarmxiepgescbupvspozqikgw/Build/Products/Debug-iphonesimulator/ExApp.app/Frameworks/RxSwift.framework
  • Framework의 정보를 확인하기위해 RxSwift.framework 상위 디렉토리로 이동
% cd /Users/jake/Library/Developer/Xcode/DerivedData/ExApp-bwhvarmxiepgescbupvspozqikgw/Build/Products/Debug-iphonesimulator/ExApp.app/Frameworks
  • file 명령어를 이용하여 dynamic framework인지 static framework인지 확인이 가능
    • "dynamically linked"라는게 있으면 dynamic framework이고, 없으면 static framework를 의미
% file RxSwift.framework/RxSwift 
RxSwift.framework/RxSwift: Mach-O 64-bit dynamically linked shared library arm64

* Mach-O의 의미: (Mach Object file format) - 애플 OS에서 동작하는 컴파일된 프로그램에 대한 파일 포맷을 의미

  • 오브젝트 파일(.o)
  • 동적 라이브러리(.dylib)
  • 정적 라이브러리(.a)
  • 번들(.bundle)

Static Framework 확인 전, Framework 직접 만드는 방법

  • Cocoapods 대부분은 Dynamic Framework이므로 Framework를 직접 만들어보고 확인
  • Xcode -> Framework 클릭하여 생성

  • JKCode.swift 파일을 만들고 샘플 코드 작성

init도 JKFramework모듈 밖에서 접근가능하도록 public으로 선언

public struct JK {
    public init() {}
    
    public func printTest() {
        print("JKCode")
    }
}
  • 만든 Framework는 디폴트로 dynamic library
    • Build Settings > mach-o 검색

  • 맨 위에서 만을었던 프로젝트에 방금 만든 프레임워크 포함하기
    • 프레임워크를 추가할 프로젝트에서 프로젝트를 선택한 후 Add Files to "Project" 선택

  • 파일은 .xcodeproj 파일을 선택하고, `Copy items if needed`를 체크한 후 저장

  • 추가 완료

  • Target > General > Frameeworks, Libraries, and Embedded Content에서 + 버튼을 클릭하여 이곳에서도 추가

  • 추가

  • 사용하는 쪽에서 import하여 사용 가능
// ExApp

import UIKit
import JKFramework // <-

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let jk = JK()
        jk.printTest() // "JKCode"
    }


}

Embed & Sign, Do Not Embed 의미

  • Embed & Sign
    • Embed 의미 - 이 프레임워크의 모든 콘텐츠를 기본 응용 프로그램과 함께 묶지 말라는 의미 (= 최종 애플리케이션 패키지에 모든 프레임워크 코드가 포함된 Frameworks라는 폴더가 포함되지 않음을 의미)
    • Sign - 프레임워크에 서명해야 하는지 여부 (이미 서명되었으므로 다시 서명 불필요)
  • 정리
    • static framework - Do Not Embed
    • dynamic framework - Embed

Static Framework 확인

  • 추가한 Framework는 디폴트값으로 dynamic library를 갖으므로, static으로 변경하기 위해 mach-o 변경

  • 빌드 후 파일 확인
    • Products > {YOUR APP NAME} > Show In Finder

  • finder > ExApp > 패키지 내용 보기

  • 빌드되어 생성된 실행파일 확인
    • 확장자명은 .app

  • 이 경로에서 Frameworks 폴더를 보면 사용한 프레임워크 항목이 존재

  • 여기서 tree . 명령어를 통해 구조를 확인
    • JKFramework.framework는 Info.plist, JKFramework, _CodeSignature가 존재
    • 만약 dynamic link가 아니고, 설정에서 Do Not Embed로 설정하면 아래 경로에 노출 x

  • 테스트) JKFramework를 Do Not Embed로 설정

  • 실행 후 다시 확인해보면 Frameworks 폴더 안에 JKFramework가 없어진 것을 확인 가능

.app 파일이 excutable인지 확인

(이어서)

  • 해당 경로에서 ls -a로 ExApp.app 파일 확인
$ ls -a
.				GoogleAppMeasurement
..				GoogleUtilities
.DS_Store			JKFramework.framework
Alamofire.o			Kingfisher.o
Alamofire.swiftmodule		Kingfisher.swiftmodule
ExApp.app			PackageFrameworks
ExApp.swiftmodule		Pods_ExApp.framework
Firebase			PromisesObjC
FirebaseAnalytics		RxSwift
FirebaseCore			XCFrameworkIntermediates
FirebaseCoreInternal		nanopb
FirebaseInstallations
  • ExApp.app 디렉토리로 들어가고 ls -a를 사용하면 ExApp이 존재
$ ls -a
.		Base.lproj	Frameworks	PkgInfo
..		ExApp		Info.plist	_CodeSignature
  • ExApp 파일을 file 명령어를 사용하여 excutable 형태임을 확인
$ file ExApp
ExApp: Mach-O 64-bit executable arm64

(ExApp의 Mach-O 타입은 디폴트로 Executable이므로)

  • 이 때 static framework는 실행 파일에 포함되므로 ExApp 실행파일 (excutable)에  같이 들어가있는 것

정리

https://holyswift.app/frameworks-embed-or-not-embed-thats-the-question/

  • static framework - Do not embed 또는 Embed 설정 
    • static framework를 Embed 시키는 경우는 media bundle에 접근하고 싶은경우 사용
    • 빌드 성공 후 생성된 .app 디렉토리에 framework 파일 존재 x (앱 실행 파일 excutable에 같이 있으므로)
    • 앱의 사이즈가 커지는 단점 존재
  • dynamic framework - Embed 설정
    • 빌드 성공 후 생성된 .app 디렉토리에 framework 파일 존재 o
    • 만약 Not Embed 할 경우 crash 발생 주의

* 참고

https://holyswift.app/frameworks-embed-or-not-embed-thats-the-question/

https://stackoverflow.com/questions/57687170/do-not-embed-embed-sign-embed-without-signing-what-are-they-what-th

https://levenshtein.tistory.com/661

Apple Document - Framework Programming Guide / Guidelines for Creating Frameworks

Apple Document - Framework Programming Guide / Frameworks and Binding

https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WhatAreFrameworks.html#//apple_ref/doc/uid/20002303-BBCEIJFI

https://stackoverflow.com/questions/57687170/do-not-embed-embed-sign-embed-without-signing-what-are-they-what-th

https://ios-development.tistory.com/1009

https://minsone.github.io/ios/mac/ios-framework-part-1-static-framework-dynamic-framework

Comments