Bundle

  • 실행 가능한 코드와 리소스를 갖고 있는 디렉토리
  • 가지고 있는 내용 - info.plist, assets, string 등
  • Framework Bundle은 Dynamic Library에서 사용하는 코드와 라소스를 포함
  • 모든 Application Bundle은 App에 대한 정보가 담긴 info.plist를 가짐

Package

Finder가 사용자에게 단일 파일로 보여주는 디렉토리

 

 

NSBundle

  • Bundle에 포함된 코드와 리소스에 대한 표현
  • NSBundle은 Objective-C 를 통해 만들어진 Foundation Class이며, Bundle 디렉토리 내에 포함된 리소스에 쉽게 접근할 수 있도록 제공하는 객체

Main Bundle

Bundle은 여러가지가 있다.

그 중 mainBundle은 App이 실행되는 코드가 있는 Bundle 디렉토리에 접근할 수 있게 도와주는 Bundle

 

 

Copy Bundle Resource

  • mainBundle에 들어가 있는 리소스 파일들은 빌드할 때, 추가됨
    • Xcode의 Build Phase에 존재 - "Copy Bundle Resources"
    • 해당 항목에서 App에 추가할 리소스를 결정
    • 해당 항목이 없는 리소스는 Project Navigator에 추가되어 있어도 실제로 Bundle을 통해 접근 불가

 

Framework

공유자원(Dynamic Library, nib, 이미지 등)을 단일 패키지로 담고 있는 디렉토리

Framework는 Library와 달리 리소스를 포함할 수 있고, Framework를 모듈 배포를 통해 Library보다 많은 활용 가능

Framework는 파일 시스템의 Bundle로 패키징되어, Core Foundation Bundle Service를 이용 가능

NSBundle class로 접근 가능

 

 

 

각각의 기능으로 분리되어 있는 프로젝트들은 공통의 리소스를 가질 수 있다.

Color, Image, Lottie의 JSON 등을 포함한다.

각각의 프로젝트들은 공통의 리소스를 사용하여 개발해야 하기 때문에, 리소스 Framework를 만들어 관리할 수 있다.

중복되는 이미지도 없고, 리소스 Framework를 import만 하면 된다.

 

Image, Color를 리소스 Framework으로 관리

먼저 리소스 Framework를 만든다. 그리고 이미지를 Images.assets에 추가한다.

 

해당 이미지들은 외부에서 코드로 불러와 사용하는 경우가 있기 때문에, 이미지를 외부에서 접근할 수 있는 코드를 만든다.

Resource Framework는 R 이라는 타입으로 접근하여 사용할 것이다.

 

먼저 R 타입을 만들자.

Framework로 만들었기 때문에, 이미지를 불러올 때 Resource Framework의 Bundle 위치를 알기 위해 내부에서 사용할 Bundle을 만들었다.

이제 이미지를 외부에서 접근할 수 있는 코드를 R.Image.[이미지이름] 형태를 따르도록 만든다.

 

 

이제 외부에서는 다음과 같이 이미지를 불러올 수 있다.

 

Color도 Image와 마찬가지로 만들 수 있다.

 

 

Storyboard, Xib를 리소스 Framework에서 관리

iOS 개발시, 항상 논쟁이 되는 주제가 있다. 바로 View를 Storyboard vs Xib로 작성하는 것이다.

 

Storyboard 파일을 갖기 위해서는 Dynamic Framework를 만들어야하는데, 각 기능마다 Framework로 만들게 되면 Framework 개수가 빠른 속도로 늘어날 뿐만 아니라, 기능을 더 작게 나눠 한 화면을 Framework로 만들면 어마어마할 것이다.

 

따라서 Storyboard, Xib를 리소스 Framework에서 관리하면 된다.

리소스 Framework에서 관리하면 화면 단위의 Framework를 Static으로 만들어도 Bundle의 위치가 리소스 Framework이기 때문에 문제가 없다.

그리고 Storyboard, Xib에서 이미지와 Color를 지정해도 Framework 자신의 내부에서 가져오기 때문에 문제가 없다.

 

그렇다면 다른 Framework에 있는 UIViewController Class와 ViewController View를 어떻게 연결할까?

 

위 사진처럼 Module을 선택하고 해당 UIViewController Class 선택하면 된다.

 

사용은

 

 

 

 

 

 

 

 

XCode에서는 Framewokr라는 것을 통해 모듈화 단위의 코드/리소스를 사용할 수 있다.

그리고 외부 소스를 가져다 사용할 때, Cocoapods, Carthage 같은 도구를 사용할 수 있다.

 

Framework에 대해 알아볼 것들

  1. 어떻게 구성되어있는가?
  2. 어떻게 동작하는가?
  3. Static/Dynamic 차이는 무엇인가?
  4. 전체적인 개발방식

Framework

Dynamic Shared Library, Nib 파일, 이미지, 다국어 문자열, 헤더 파일 등과 같이 공유 리소스를 패키지로 캡슐화하는 계층 구조 파일 디렉토리 이다.

그리고 Framework도 Bundle이며 NSBundle로 접근이 가능하다.

또한, 리소스 사본은 프로세스 수에 상관없이 항상 물리적으로 메모리에 상주하며, 리소스 공유로 풋 프린트를 줄이고 성능을 향상시킨다.

 

Dynamic Framework

XCode에서 Framework를 만들면 기본적으로 Dynamic Framework로 만들어진다.

Dynamic Framework는 동시에 여러 프레임워크 또는 프로그램에서 동일한 코드 사본을 공유하고 사용하므로, 메모리를 효율적으로 사용한다.

동적으로 연결되어 있으므로, 전체 빌드를 다시하지 않아도 새로운 프레임워크 사용이 가능하다.

 

Static Linker를 통해 Dynamic Library Reference가 Application 코드(Heap)에 들어가고, 모듈 호출시 Stack에 있는 Library에 접근하여 사용한다.

 

Static Framework

Static Framework는 Static Linker를 통해 Static Library 코드가 Application 코드 내로 들어가 Heap 메모리에 상주한다.

따라서 Static Library가 복사되므로, Static Framework를 여러 Framework에서 사용하게 되면, 코드 중복이 발생한다.

 

Library는 Framework가 아니라 Static Library가 복사된 곳에 위치하므로, Bundle의 위치는 Static Framework가 아닌 Static Library가 위치한 곳이 된다.

때문에 번들을 접근할 때는 스스로가 접근하기보다는 외부에서 Bundle의 위치를 주입받는 것이 좋다.

 

어떤 타입을 사용해야 하는가?

일반적으로 리소스를 스스로 갖고 있거나 전체 소스를 제공하는 경우 -> Dynamic Framework

그렇지 않고 SDK 형태로 배포하는 경우 -> Static Framework

 

 

 

 

 

Framework

  • 코드(클래스, 프로토콜, 컴포넌트)/리소스들을 모듈화한 모음
  • 사용하는 주체와 IoC(제어의 역전) 관계
  • 특정 개념들의 추상화를 제공하는 여러 클래스나 컴포넌트로 구성되어 있다.
  • 컴포넌트들은 재사용 가능
  • 고수준에서 조작 가능
  • iOS에서 제공하는 Cocoa Touch 프레임워크가 존재한다.

Library

  • Application이 연결할 수 있는, 패키징된 객체 파일들의 모음
  • 사용하는 주체가 기능을 요청하며 사용한다.
  • 즉, 개발자가 만든 클래스에서 직접 호출해서 사용

 

차이점

제어의 흐름에 대한 주도성이 누구에게 있는가에 달렸다.

즉, Application의 Flow를 누가 쥐고 있는가?

  • 프레임워크는 전체적인 흐름을 스스로가 쥐고 있고, 사용자는 그 안에서 코드를 넣는다.
  • 라이브러리는 사용자가 전체적인 흐름을 만들고, 라이브러리를 필요한 곳에서 가져다 쓴다.

다시 말해, "라이브러리는 라이브러리를 사용하는 측에 주도성이 있고, 프레임워크는 그 틀안에 주도성을 갖고 있다" 고 볼 수 있다.

 

 

제어의 역전(IoC)

어떠한 일을 하도록 만들어진 프레임워크에 제어의 권한을 넘김으로써, 클라이언트 코드가 신경쓰는 것을 줄이는 전략

내가 라이브러리의 메소드를 사용하는 것은 쉽게 이해할 수 있다.

결국, 프레임워크의 메소드가 사용자의 코드를 호출한다... 인데

어떻게 프레임워크가 내 메소드를 호출하는가?

  1. 쉬운 방법 : 프레임워크의 event, delegate에 나의 메소드를 등록시키는 것
  2. DI : 프레임워크에 정의된 protocol 을 나의 코드에서 구현, 상속한 후에 프레임워크에 넘겨준다.
    1. 이는 객체를 프레임워크에 주입하는 것이다.

 

 

 


모듈화

하나의 프로젝트에 모든 기능들을 넣어서 개발하다보면 어느 순간 단점들이 생긴다.

  1. 컴파일 속도
  2. 하나의 코드를 고쳤을 때, 발생하는 사이드 이펙트

따라서 모듈화를 통해 결합도를 낮추고, 응집도를 높히는 작업

 

출처 : http://minsone.github.io/ios/mac/ios-enterprise-app-configuration-1

  • Module : 라이브러리를 가진 프로젝트로, 특정 역할(네트워크, Custom UI 등)을 수행, 외부에는 정의한 protocol을 통해 호출가능하게 한다. 
  • Module Package : 모듈들을 관리, 모듈들의 결합으로 기능을 확장
  • Service : 특정 도메인, 서비스를 관리하는 프로젝트
  • Common Service : 인증, 보안 등 다른 서비스에서 공통으로 사용되는 서비스
  • Main Service : 각 서비스들을 호출 및 연결
  • Application : UIApplication에서 제공하는 기능을 받아서 처리

 

장점

  1. 메인 프로젝트에서의 라이브러리 의존성이 사라짐
  2. Widget, Watch 등을 개발할 때, 모듈을 쉽게 사용할 수 있음
  3. Clean Build시에는 빌드가 느리지만, Rebuild시에는 해당 수정 부분만 컴파일되므로 훨씬 빨라짐

 

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts