study record
[iOS] Xcode 프로젝트 개념 (xcodeproj, xcworkspace의 차이) 본문
Project는 하나 이상의 Product를 build하기 위해 필요한 모든 파일과 리소스 및 정보를 담고있는 저장소이다.
Xcode에서 프로젝트 파일을 만들면
프로젝트이름.xcodeproj 파일이 만들어진다.
이를 우클릭하여 '패키지내용보기'를 클릭하면 그 안의 파일들을 볼 수 있다.
프로젝트이름.xcodeproj 디렉토리 안에는 아래의 것들이 존재한다.
1. project.pbxproj 파일
2. project.xcworkspace 파일
3. xcuserdata 디렉토리
4. xcshareddata 디렉토리
하나씩 살펴보자!
1. project.pbxproj 파일
- 프로젝트에 관한 모든 정보를 저장
- 두 브랜치에서 각각 작업할 때에 파일 생성, 이동, 삭제 등을 했을 때 이 파일에 수정이 생겨 git conflict나는 경우가 잦다.
- 16진 해시 형태의 객체의 Identifier를 추적하여 section이라는 의미 있는 단위로 관리하는 파일
- 프로젝트 내부에서 파일들을 파일 유형에 따라 reference를 저장
- PBXBuildFile, PBXFileReference, PBXGroup 등 다양한 객체가 존재한다.
예시)
/* Begin PBXBuildFile section */
1234567890ABCDEF00112233 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1234567890ABCDEF00112234 /* main.m */; };
1234567890ABCDEF00112235 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1234567890ABCDEF00112236 /* AppDelegate.m */; };
/* End PBXBuildFile section */
예시 디테일하게 보기
Xcode 프로젝트 파일(.pbxproj)에서 파일과 관련된 객체들을 관리하기 위한 주요 요소들
PBXBuildFile, PBXFileReference, PBXGroup
1) PBXBuildFile?
PBXBuildFile은 Xcode 프로젝트에서 사용하는 project.pbxproj 파일 내에 정의된 객체 유형 중 하나로, 특정 소스 파일이나 리소스를 빌드 단계에 연결하는 역할을 한다.
PBXBuildFile 객체는 빌드 대상(Target)에 포함된 파일을 나타내며, 이 파일들이 어떻게 빌드되고 사용하는지 설정하는 역할을 한다.
fileRef 필드는 실제 파일을 참조하는 PBXFileReference 객체의 ID이다.
isa는 Xcode의 project.pbxproj 파일 내에서 사용되는 키로, 특정 객체가 어떤 클래스에 속하는지(즉, 객체의 유형을) 나타낸다. isa는 "is a"의 줄임말로, 객체의 타입 정보를 정의하는 역할을 한다.
앞의 16진수와 file ref의 16진수는 다르다.
1234567890ABCDEF00112233는 PBXBuildFile 객체의 고유 ID로, PBXBuildFile section에서 어떤 PBXBuildFile 객체인지 확인하는 것이고,
이 객체를 어떻게 처리할지를 확인하는 것이 fileRef를 통해 실제 파일을 확인(실제 파일의 위치나 정보를 가리키는 참조하는 역할)하여 처리 방법을 결정하는 것이다.
흐름을 정리해 보면:
- Xcode가 00FF0022F4123F7BFE97A9F8이라는 ID로 PBXBuildFile객체를 식별한다.
- 이 PBXBuildFile객체의 fileRef 필드가 FE3E0DBC2FCC14709385306A라는 ID로 참조된 파일을 확인한다.
- 이 참조된 ID는 실제 파일(ImageStyle.swift)을 나타내는 PBXFileReference객체이다. 컴퓨터는 이를 통해 이 빌드 파일이 어떤 소스 파일인지, 또는 어떤 리소스 파일인지를 알 수 있다. 이를 통해 Xcode가 해당 파일을 어떻게 처리할지 결정한다.
2) PBXFileReference?
프로젝트 내에서 파일 자체를 참조하는 객체
파일의 경로나 유형, 파일 이름을 정의하며, Xcode 프로젝트의 파일 시스템에서 파일을 식별할 수 있도록 한다.
/* Begin PBXFileReference section */
ABCD1234EFGH5678 /* MyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
path는 파일의 경로를 나타내고,
lastKnownFileType은 파일 유형(예: Swift 소스 파일)을 나타낸다.
PBXFileReference는 파일의 메타데이터를 정의하며, 이 파일이 프로젝트의 어떤 부분에 위치하는지 설명한다.
3) PBXGroup?
PBXGroup는 Xcode 프로젝트 내에서 파일을 계층 구조로 조직하는 데 사용된다.
그룹은 파일과 폴더를 포함할 수 있으며, 프로젝트 내에서 파일 시스템을 관리하는 방식과 유사한 방식으로 파일을 그룹화한다.
/* Begin PBXGroup section */
ABCD5678EFGH1234 /* Main Group */ = {
isa = PBXGroup;
children = (
ABCD1234EFGH5678 /* MyViewController.swift */,
ABCD8765EFGH4321 /* Assets.xcassets */
);
sourceTree = "<group>";
name = "Main Group";
};
/* End PBXGroup section */
children 아래에 속한 ID는 fileRef이다. 프로젝트의 파일 트리에서 파일 구조화할 때 파일 경로나 유형을 정의할 때 사용하는 듯!
같은 fileRef를 PBXBuildFile, PBXGroup에서 사용하고 확인하며 프로젝트 빌드, 구조화할 때 사용한다.
2. project.xcworkspace 파일
project.xcworkspace도 마찬가지로 '패키지내용보기'를 클릭하면 그 안의 파일들을 볼 수 있다.
contents.xcworkspacedata 에서는 워크스페이스가 참조하고 있는 프로젝트를 확인할 수 있다.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
한 워크스페이스에 여러 프로젝트를 갖도록 구성한다면 다음과 같이 2개의 프로젝트를 참조하게 된다.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:App2/App2.xcodeproj">
</FileRef>
<FileRef
location = "group:App/App.xcodeproj">
</FileRef>
</Workspace>
xcodeproj, xcworkspace의 차이
는 다루는 범위와 사용 목적이 다르다는 것에 있다.
.xcodeproj 파일은 Xcode에서 단일 프로젝트를 관리하기 위한 파일 형식이다.
이 파일은 프로젝트 내에서 사용하는 파일, 설정, 빌드 설정, 스킴(scheme) 등 다양한 정보를 포함하고 있다. 일반적으로 단일 애플리케이션이나 단일 라이브러리를 개발할 때 사용한다.
일반적으로 하나의 앱이나 라이브러리를 개발할 때 사용하고, 작은 규모의 프로젝트에서 의존성이 적고 별도의 프레임워크나 라이브러리가 없는 경우에 사용한다.
.xcworkspace 파일은 여러 프로젝트를 한 곳에서 관리하기 위한 파일 형식이다.
여러 프로젝트를 하나의 통합된 환경에서 작업할 수 있도록 하며, 모듈화된 프로젝트나 라이브러리 의존성이 있는 경우에 주로 사용된다. 워크스페이스는 단일 프로젝트뿐만 아니라 여러 프로젝트와 라이브러리를 통합하여 관리할 수 있는 상위 구조이다.
- 워크스페이스 내에 포함된 여러 프로젝트의 참조를 저장.
- 각 프로젝트의 설정은 개별 .xcodeproj 파일에 유지되며, xcworkspace는 이들을 통합 관리.
사용 사례
- 모듈화된 프로젝트: 여러 모듈(서브 프로젝트)을 독립적으로 개발하면서 하나의 워크스페이스에서 작업하고 싶을 때.
- 외부 라이브러리 관리: CocoaPods나 Swift Package Manager를 통해 추가된 의존성 라이브러리들을 워크스페이스 내에서 통합 관리할 때.
Q. 외부 라이브러리를 사용할 때에 xcworkspace를 사용해야 하는 이유?
- CocoaPods 예시:
- CocoaPods는 외부 라이브러리들을 Podfile에서 정의하고, 이를 설치하면 Pods.xcodeproj라는 독립적인 프로젝트 파일을 생성한다. 이 Pods.xcodeproj는 의존성 라이브러리의 소스 코드와 빌드 설정을 포함하는 별도의 Xcode 프로젝트이다.
- Pods.xcodeproj와 원래 프로젝트(MyApp.xcodeproj)를 동시에 관리하고 의존성을 설정하려면 xcworkspace가 필요하다. xcworkspace는 두 프로젝트를 하나의 통합된 환경에서 빌드하고, 종속 관계를 관리할 수 있게 해준다.
- Swift Package Manager (SPM) 예시:
- Swift Package Manager를 사용해 외부 패키지를 추가할 때도, Xcode는 외부 패키지를 개별 프로젝트로 인식한다. 이런 패키지들을 관리하려면 xcworkspace를 통해 주 프로젝트와 패키지 간의 빌드 및 의존성을 관리할 수 있다.
- xcodeproj로만 작업할 경우:
- xcodeproj만 사용하면 각 외부 라이브러리와 메인 프로젝트 간의 의존성 설정을 수동으로 처리해야 할 수 있다.
또한 xcworkspace를 사용하면 여러 프로젝트가 한 곳에서 통합적으로 빌드해준다.
예를 들어, 외부 라이브러리 Pods.xcodeproj나 SPM 패키지 프로젝트가 메인 프로젝트와 동일한 빌드 프로세스 안에서 빌드되므로, 의존성 라이브러리와 프로젝트 간의 빌드 설정 충돌이나 링크 오류를 방지할 수 있다.
따라서 외부 의존성을 가진 프로젝트라면 xcworkspace가 권장된다.
- 프로젝트 간 의존성을 자동으로 관리하고, 외부 라이브러리와 메인 프로젝트 간의 빌드 및 링크를 일관성 있게 처리한다.
- 빌드 설정 충돌을 줄이고, 외부 라이브러리와 프로젝트 간의 통합 빌드 프로세스를 제공한다.
- 협업 환경에서 팀원들이 동일한 의존성 설정을 사용할 수 있도록 하여, 프로젝트 설정의 일관성을 유지한다.
3. xcuserdata 디렉토리, xcshareddata 디렉토리
다음은 마지막으로 xcodeproj, xcworkspace 모두에 속해있던 두 디렉토리이다.
각각은 사용자별 혹은 공유할 설정 데이터를 저장하는 역할을 한다.
프로젝트 설정에 영향을 미치지 않으면서 개발 환경에서 유용한 사용자 설정을 관리한다.
프로젝트 작업 환경에 맞게 사용자 설정이나 공유 설정을 저장한다.
xcuserdata 디렉토리
xcuserdata 디렉토리는 Xcode 프로젝트의 사용자별 설정 정보를 저장하는 디렉토리이다. 특정 사용자가 Xcode에서 프로젝트를 열었을 때 해당 사용자가 만든 설정들이 여기에 저장된다. 주로 사용자 고유의 환경 설정, 디버깅 세션 데이터, 편집 상태 등 사용자만이 사용하는 설정을 관리한다.
저장하는 정보: 주로 파일 북마크, 최근 열었던 파일, Breakpoint 설정, 디버그 레이아웃 등.
xcshareddata 디렉토리
xcshareddata 디렉토리는 프로젝트 내에서 모든 사용자가 공유할 수 있는 설정 데이터를 저장하는 디렉토리이다. 이 디렉토리는 주로 프로젝트의 공통 설정을 저장하며, 다른 팀원들과 공유하기 위한 설정을 포함한다. 이 디렉토리에 저장된 내용은 버전 관리 시스템(Git 등)에 포함될 수 있으며, 모든 개발자가 동일한 설정을 사용할 수 있다.
저장하는 정보: 프로젝트의 공통 스킴(scheme), 테스트 플랜(test plan), 코드 커버리지 설정 등.
다음 글에서는 Scheme, Target 에 대해서 다뤄보겠습니다!
참고한 글
- https://ios-development.tistory.com/406
- https://levenshtein.tistory.com/658
'iOS > iOS 정리' 카테고리의 다른 글
[iOS] iOS Framework (0) | 2022.07.22 |
---|---|
[iOS] iOS 레이아웃 사이클 (0) | 2022.04.06 |
[iOS] invalidateIntrinsicContentSize() (0) | 2022.04.05 |
[iOS] UIView의 Layer란? (0) | 2022.04.01 |
[iOS] UIResponder (0) | 2022.03.30 |