이재용의 iOS

Xcode Project 알아보기

2022년 12월 5일 • ☕️ 4 min read


Xcode에서 프로젝트를 생성할 때 어떤 파일들과 디렉토리가 생성되는지 알아보고자 합니다. 정리를 위한 글이기 때문에 ~니다 체로 작성했습니다.


Project

An Xcode project is a repository for all the files, resources, 
and information required to build one or more software products

Project는 Application을 빌드하기 위한 파일, 리소스, 정보를 담은 repository입니다. 처음 Xcode를 켜고 Single View Application을 생성하면 Project를 생성하게 됩니다. 이 때, 프로젝트의 디렉토리를 살펴보게 되면 프로젝트명.xcodeproj라는 파일이 생긴 것을 확인할 수 있습니다. 정확히 얘기하면 파일이 아니라 디렉토리입니다. 터미널이나 오른쪽 클릭하여 “패키지 내용 보기”를 통해 해당 디렉토리로 들어가게 되면 project.phxproj이라는 파일과 xcuserdata, project.xcworkspace라는 디렉토리가 존재합니다.

  • project.phxproj는 프로젝트의 설정 파일입니다.
    project.phxproj는 실제 프로젝트의 설정 파일응 담고 있습니다. Xcode를 실행하여 프로젝트의 최상단 설정파일을 누르면 General, Signing & Capabilites, Resource Tags 등 여러 메뉴들이 보입니다. 이 모든 메뉴들의 설정을 파일 유형별로 저장하고 있습니다.

Git을 사용하여 협업할 때 충돌이 일어나는 파일 중 하나입니다. A와 B가 함께 프로젝트의 설정 파일을 건들일 경우, 두 명은 설정 파일의 서로 다른 reference를 가지고 있기에 충돌이 일어납니다. 설정 파일에서 충돌이 일어났을 때 치명적인 것은 프로젝트가 열리지 않기 때문에 터미널이나 Git GUI(형상 관리 툴)를 이용하여 해결해야 합니다. 이러한 치명적인 단점을 해결하기 위해 프로젝트 생성 도구인 xcodegen, tuist를 이용할 수 있습니다.

  • xcuserdata는 프로젝트의 개인 설정을 담은 디렉토리입니다.
    breakpoint, UI layout, 스냅샷 설정을 담은 프로젝트 자체에 크게 영향을 주지 않는 디렉토리입니다.
  • project.xcworkspace는 여러 개의 Project를 담아 관리할 수 있도록 해주는 디렉토리입니다.
    Single View Application을 생성하더라도 Workspace를 생성하는 것으로 보아, Swift Package Manager때문인 것으로 추측됩니다. (Swift Package Manager 다음 공부 타겟 ✔️) 이렇게 추측한 이유는 아래에서 설명할 수 있을 듯 합니다.

Workspace

Workspace는 여러 개의 Project를 담아 관리할 수 있도록 해주는 개념입니다. 대부분 CocodaPods를 처음 사옹할 때 접해보았을 것입니다. CocoaPods는 본래의 프로젝트와는 별도로 Project를 만들어서 라이브러리 의존성을 관리할 수 있도록 해주는 도구입니다.

Workspace가 생성되면 Project.xcodeproj과 유사한 디렉토리인 project.xcworksapce가 생성됩니다. project.xcworkspace 디렉토리에 들어가보면 contents.xcworkspacedata 파일과 xcuserdata, xcsharedata 디렉토리가 있습니다.

  • contents.xcworkspacedata는 프로젝트의 reference를 저장하고 있습니다.
    workspace에 포함된 프로젝트들의 reference를 저장한 xml파일입니다. workspace에 프로젝트를 추가하면 해당 파일에 reference가 추가됩니다.
  • xcuserdataworkspace의 개인 설정을 담은 디렉토리입니다.
  • xcsharedataworkspace에 공유된 설정을 담은 디렉토리입니다.

Workspace와 SubProject의 차이

Xcode는 여러 개의 프로젝트를 다룰 수 있는 Workspace를 만드는 기능도 제공되지만, 프로젝트 안에 SubProject를 생성하여 이를 관리할 수도 있습니다. 이와 같은 방식이 활용되는 경우는 오픈소스로 배포되는 라이브러리에서 라이브러리 코드가 담긴 Project와 라이브러리를 사용하여 만든 예제 Project를 나누고 싶은 경우가 있는데 이 때 SubProject로 예제 Project를 활용할 수 있습니다.

물론 이 또한 Workspace를 통해 관리할 수도 있습니다. 다만 두 방식의 차이점은 SubProject는 Project 사이의 부모-자식 관계가 생기고 Workspace는 형제 관게라는 점입니다. 부모-자식 관계이므로 부모 Project는 자식 Project의 reference를 가질 수 있지만 그 반대는 불가능합니다. 하지만 형제관계일 경우 어떤 Project든 다른 Project의 reference를 가질 수 있습니다.


Target

A target specifies a product to build and contains the instructions 
for building the product from a set of files in a project or workspace. 

Target은 프로젝트를 통해 생성되는 Application입니다. 이는 일반적으로 하나의 모듈을 의미합니다. “Target은 Application이다”라는 말의 의미는 좀 더 구체적으로 말하자면, “Target은 Xcode의 빌드를 통해 생성된 최종 product이다”와 의미가 같습니다. 즉, Target은 프로젝트를 어떻게 빌드할 것인지를 담당합니다.

Xcode에서 프로젝트 최상단 설정파일을 누르면 project 하위에 target 섹션이 있고, 여기서 프로젝트의 target을 관리할 수 있습니다. 기본적으로 Target은 프로젝트 생성 시, 1개만 생성되지만 목적에 따라 하나의 프로젝트에 여러개의 Target을 생성할 수 있습니다.

  • 각각의 target은 프로젝트의 build setting을 설정할 수 있습니다.
  • 각각의 target은 프로젝트에 포함된 객체, 리소스 혹은 별도의 스크립트를 따로 설정할 수 있도록 해줍니다.
  • 하나의 프로젝트를 여러 개의 배포판으로 사용할 수 있도록 해줍니다. (iPhone target, iPad target 등)

Scheme

Target이 프로젝트를 빌드, 프로파일, 테스트 등을 할 때 일어날 일들을 정의할 수 있도록 해주는 항목입니다. Target은 1개 이상의 Scheme을 가질 수 있는데 한 번에 하나의 Scheme만이 작동할 수 있습니다. 이 Scheme에서는 프로젝트 빌드시 사용되는 환경변수나 인자를 넘겨줄 수 있습니다.

Scheme은 프로젝트의 런타임에서 일어날 일을 설정할 수 있습니다. 이 때 사용되는 대표적인 것 중 하나가 Build Configuration입니다. Scheme에서 Build Configuration을 설정할 수 있습니다. Build, Run, Test, Analyze는 Build Configuration이 기본적으로 Debug로 설정되어 있고, Profile, Archive는 Release로 설정되어 있습니다.

#if DEBUG
    print(error)
#endif

위 코드는 Build Configuration이 Debug로 설정된 Scheme에서 작동하는 print문입니다. 이와 같은 것을 가능하게 해주는 것이 Xcode의 PreProcessor입니다.