[iOS] Dynamic Framework & Static Framework

2023. 4. 1. 21:40iOS

반응형

요즘 회사 프로젝트의 크기가 커지다보니 각 모듈간의 의존도도 커지고 빌드 시간도 오래 걸리게 되면서, Framework 단위로 분리해서 관리하는 방법에 관심을 가지게 되었습니다.

 

그러다보니 모르는 부분들도 있어서 이전에는 가볍게 알고 있던 Static Framework & Dynamic Framework에 대해 좀 더 깊게 알아보려고 합니다 🙃

 

Dynamic Framework

우선 Dynamic Framework는 Xcode에서 Framework를 생성하게 되면 기본적으로 Dynamic Framework로 생성됩니다. Dynamic Framework는 그림에서처럼 Static Linker를 통해 Dynamic Library ReferenceApplication Code로 들어가고 사용시에는 해당 참조를 이용해서 실행됩니다.

 

음,, 말이 조금 어려운데, 우선 Dynamic Framework를 프로젝트에 추가하고 빌드하게 되면 해당 프레임워크의 excutable binary 파일이 앱의 excutable binary와는 별도로 생성됩니다. 그리고 앱에서는 해당 모듈을 사용할 때, 참조만 가지고 있다가 사용하게 되는 원리입니다.

 

요렇게 실행 시에 참조를 통해 사용하는 방식이기 때문에, 컴파일은 빠르지만 앱이 실행되는 속도는 레퍼런스를 런타임에 찾기 때문에 상대적으로 느리게 됩니다.

 

어려우니까 한번 직접 Dynamic Framework를 직접 만들어서 사용하면서 알아볼게요~

우선 Framework를 선택해서 하나 생성해주세요~

그리고는 테스트를 위해 Framework 내부에 요런 클래스를 하나 구현했습니다.

이제 생성했던 Framework 테스트를 위해 앱 프로젝트에 추가해주겠습니다. 앱의 프로젝트에 Add Files to “App Name”을 클릭해서 아까 만들어주었던 Framework의 프로젝트 파일을 추가해줍니다.

그리고 GeneralFrameworks, Libraries, and Embedded Content+를 눌러 Framework를 추가해주세요. 추가하게 되면 Embeded & Sign, Do Not Embed의 메뉴가 선택가능한데 우선 Embeded & Sign 메뉴를 선택한 상태로 나두시면 됩니다 ! (이 부분은 뒤에서 알아볼게요 😄)

이제 앱에서 해당 Framework를 사용해서 빌드를 해볼게요. 해당 Framework를 import하고 내부의 TestHelper를 접근하면 잘 접근되고 빌드까지 성공하는 것을 알 수 있습니다.

우선 가볍게 Dynamic Framework를 사용하는 방법을 알아봤습니다. 다음으로는 Static Framework를 사용하는 법에 대해 간단히 알아보고 살짝 딥하게 비교하면서 다뤄볼게요

 

Static Framework

Static FrameworkStatic Linker를 통해 레퍼런스가 아니고 Static libraries가 복사되어서 Application Code로 들어가게 됩니다.

 

아까 Dynamic Framework는 앱의 excutable binary와는 별도로 생성되고 레퍼런스만 참조한다고했었죠? 반대로 Static Framework에서는 앱의 excutable binary 파일에 같이 복사되어서 포함됩니다. 그렇기 때문에 더 파일이 커질 수 있겠죠?

 

Framework가 컴파일 타임에 포함되기 때문에, 빌드속도는 늘어나지만 런타임 중에 레퍼런스를 찾는 작업이 없기 때문에 앱 실행속도는 더 빠르게 됩니다.

 

이제 Static Framework도 만들어보겠습니다. 아까 만들었던 Dynamic Framework를 바꾸어볼게요. 만들었던 Framework의 Build SettingsMach-O Type을 들어가주세요.

기본적으로 생성할 때, Dynamic Framework이기 때문에 Dynamic Library로 선택되어있을겁니다. 요거를 Static Library로 변경해주세요 !

그리고 앱의 프로젝트에서 만들었던 Framework를 Embeded & Sign으로 선택했었죠? 이거를 Do Not Embed로 변경해주세요 !

이제 빌드하게되면 동일하게 성공하게 될거에요 !

 

그렇다면 왜 Dynamic Framework & Static Framework 각각 Embed 방식을 다르게 가져가는걸까요? 요걸 이제 살짝 딥하게 알아볼게요

 

Dynamic Framework & Static Framework 

우선 아까 Dynamic Framework를 Embed하는 방식은 Embeded & Sign을 선택했었죠? 한번 해당 옵션을 선택한 뒤, 빌드를 해서 내부의 패키지를 확인해보겠습니다

 

빌드를 하고 생성된 Products에 우클릭을 하고 Show in Finder를 선택해주세요 ~

그리고 Finder에서 패키지 내용 보기를 클릭해서 들어가면 앱의 excutable binary 파일을 볼 수 있습니다

여기서 이제 중요한건 아까 Dynamic Framework는 Framework의 excutable binary 파일이 따로 생성되고 앱에서는 레퍼런스를 얻어서 사용한다고 했었죠. 그렇다면 한번 Framework의 excutable binary 파일을 찾아볼게요

 

패키지 내용 보기를 통해 들어간 곳에 Frameworks 폴더를 타고 가다보면 우리가 만든 Framework의 excutable binary 파일을 쉽게 확인할 수 있습니다. 와우,, 이래서 Dynamic Framework는 별도의 excutable binary가 생성되고 이를 참조해서 사용한다는 말이 이해가 조금은 되죠?

자.. 근데 만약 여기서 Embed 방식을 Do Not Embed로 변경하고 빌드하면 어떻게 될까요?

다시 빌드해서 패키지 내용을 확인해보면 Framework의 excutable binary 파일이 없어진 것을 확인할 수 있습니다 😎

Dynamic Framework의 경우에는 런타임 중에 Framework의 레퍼런스로 찾는다고 했는데, excutable binary가 없어졌으니.. 빌드는 가능하지만 실행을 시켜보면 런타임 중에 링크를 찾기 위해 Frameworks를 찾는데 없기 때문에 dyld: Library not loaded라는 에러가 발생해서 죽게 됩니다.

 

이런 이유때문에, Dynamic Framework를 사용하는 경우에는 Embeded & Sign 옵션을 선택해서 Framework의 별도 excutable binary 파일이 포함될 수 있게 설정해주어야 합니다.

 


⭐️ TIP ⭐️

  • Dynamic Framework의 Linker가 Framework의 레퍼런스를 찾는 위치는 @rpath(Runpath Search Path)로 프로젝트의 설정에서 확인가능합니다.

  • 해당 프로젝트에서 사용하는 shared library의 경우는 터미널의 $otool -L TestProject 명령어를 통해 확인할 수 있습니다


 

이제 Static Framework의 경우를 알아보겠습니다. Static Framework의 경우는 Do Not Embed로 설정을 했었죠?

그렇다면 이 경우에는 앱의 excutable binary에 어떻게 포함되어있는지 확인볼게요 😀

 

다시 Dynamic Framework로 설정했던 부분을 Static Framework로 변경해주고 빌드를 해주세요. 그리고 이번에는 터미널에서 한번 excutable binary 파일을 확인해주도록 할게요 !

 

터미널 환경에서 패키지 내용 보기의 위치까지 디렉토리를 우선 이동해주세요~

여기서 $nm -debug-syms TestProject | grep “\\.o” 명령어를 입력해주세요. 이 명령어를 통해서 excutable binary 파일에 포함되어 있는 symbol중 object 파일만을 확인할 수 있습니다.

 

오.. 확인해보니 Static Framework에서는 해당 앱 프로젝트의 파일 외에도 Framework의 TestHelper 파일이 포함된 것을 확인할 수 있죠?!

$nm 명령어를 사용하면 라이브러리, 컴파일된 오브젝트 모듈, 공유 오브젝트 파일, 실행파일등의 바이너리 파일을 검사해서 그 파일의 저장된 내용 및 메타 정보를 확인가능합니다.

만약 반대로 Static Framework의 Embed 방식을 Embeded & Sign으로 변경하면 어떻게 될까요?

 

해당 패키지 내용 안에 Framework의 excutable binary 파일이 별도로 생성되지만 이미 앱의 excutable binary 파일 안에 포함되어 있으므로 중복으로 포함되는거라 결국 필요없게 됩니다. 그렇기 때문에, Static Framework의 경우에는 Do Not Embed로 설정하면 됩니다.

 

오늘은 Static Framework & Dynamic Framework에 대해 알아보았는데요.

평소에 설정을하고 사용했지만 내부는 잘 몰랐던 부분에 대해 알 수 있었습니다

오늘 내용도 도움이 되었으면 좋겠네요 감사합니다 😄

반응형