# macOS 앱의 구조

> Clean Markdown view of GeekNews topic #24923. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24923](https://news.hada.io/topic?id=24923)
- GeekNews Markdown: [https://news.hada.io/topic/24923.md](https://news.hada.io/topic/24923.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-09T04:33:02+09:00
- Updated: 2025-12-09T04:33:02+09:00
- Original source: [eclecticlight.co](https://eclecticlight.co/2025/12/04/the-anatomy-of-a-macos-app/)
- Points: 10
- Comments: 1

## Summary

macOS 애플리케이션은 **번들(bundle)** 구조를 통해 실행 파일과 리소스, 설정 정보를 하나의 디렉터리로 통합합니다. Classic Mac OS의 리소스 포크 방식에서 발전한 이 구조는 **Contents 폴더**를 중심으로 MacOS·Resources·Frameworks 등의 하위 디렉터리를 포함하며, Info.plist가 앱의 정체성을 정의합니다. 이후 코드 서명과 공증이 더해지며 보안이 체계화되었고, 이러한 **자급적 구조**는 설치와 업데이트를 단순화하면서 macOS 생태계의 일관성을 유지하는 기반이 되었습니다.

## Topic Body

- macOS 애플리케이션은 **명령줄 프로그램보다 복잡한 구성 요소**를 가지며, 창과 메뉴 등 인터페이스 자원을 별도 구조로 관리함  
- **Classic Mac OS**에서는 실행 코드와 리소스가 파일의 리소스 포크에 저장되었으나, **Mac OS X**부터는 **번들(bundle)** 구조로 전환됨  
- 앱 번들은 **Contents 디렉터리**를 중심으로, **MacOS·Resources·Frameworks** 등의 하위 폴더와 **Info.plist** 같은 핵심 파일로 구성됨  
- 이후 **코드 서명·App Store 영수증·공증(notarization)** 등이 추가되며, 보안과 무결성을 강화한 구조로 발전함  
- 이러한 **자급적(app bundle) 구조**는 설치·업데이트·삭제를 단순화하고, **보안성과 유지관리 효율성**을 높이는 핵심 기반이 됨  

---

### Classic Mac OS의 앱 구조
- 초기 Mac OS에서는 창, 메뉴 등 **UI 리소스**를 실행 파일과 분리해 **리소스 포크(resource fork)** 에 저장  
  - 예시로 **QuarkXPress 4.11**의 리소스가 **ResEdit**에서 표시됨  
  - 실행 코드는 **CODE 리소스**에 포함되며, Finder가 인식할 수 있도록 **파일 유형(type)과 생성자(creator)** 정보가 함께 저장됨  

### Mac OS X의 번들 구조
- **Mac OS X**는 **NeXTSTEP**에서 유래한 **번들(bundle)** 구조를 도입  
  - 앱은 `.app` 확장자를 가진 디렉터리 형태이며, 내부에 **Contents** 폴더를 포함  
  - **MacOS 폴더**에는 GUI 앱의 실행 파일과 명령줄 도구가 포함됨  
  - **Resources 폴더**에는 앱 아이콘, GUI 구성 요소 등 리소스 파일이 저장됨  
  - 일부 앱은 **Frameworks 폴더**를 포함해 **dylib(동적 라이브러리)** 를 내장함  
- **Info.plist** 파일은 필수이며, 실행 파일 이름, 아이콘, 최소 macOS 버전, 문서 유형, 버전 번호 등을 정의  
- **PkgInfo** 파일은 Classic Mac OS의 유형·생성자 정보를 유지하지만 필수는 아님  
- 앱 실행 시 **launchd**가 실행 코드를 시작하며, **LaunchServices**와 **RunningBoard**가 **Info.plist** 정보를 기반으로 초기화 절차를 수행  

### macOS에서의 보안 및 확장
- **Mac OS X 10.5 Leopard(2007)** 부터 **코드 서명(Code Signature)** 이 도입되어 `_CodeSignature` 폴더가 추가됨  
  - **CodeResources 파일**에 코드 디렉터리 해시(CDHash)가 포함되어 앱 무결성을 검증  
- **App Store 배포 앱**은 `_MASReceipt` 폴더에 **스토어 영수증**을 포함  
- **2018년 이후**에는 **공증(notarization)** 이 도입되어, Apple이 발급한 **티켓(ticket)** 을 **CodeResources 파일**로 번들에 ‘스테이플(staple)’ 가능  
- 현대 앱 번들은 과거에 시스템 폴더에 설치되던 구성 요소를 자체 포함  
  - **Library 폴더**: LaunchDaemons, LoginItems 등  
  - **XPCServices 폴더**: 앱이 사용하는 별도 실행 서비스  
  - **Plugins / Extensions 폴더**: 앱 확장 기능 및 **App Intents** 포함  
  - 일부 앱에는 **version.plist** 파일도 존재  

### 앱 번들의 이점
- 모든 구성 요소를 **번들 내부에 통합**함으로써 설치·업데이트·삭제가 간편해짐  
- 구성 요소 누락 가능성이 줄고, **서명 및 공증 보호**를 통해 **보안성**이 강화됨  
- **App Store 앱**은 추가적으로 **영수증 및 공증 티켓**을 포함해 신뢰성을 확보  
- **Intel과 Arm 아키텍처** 간 구조 차이는 없으며, **Mach-O 실행 파일**이 두 플랫폼용 코드를 모두 포함하는 **유니버설(fat) 바이너리** 형태로 저장됨  
  - 동일 파일 내에 각 아키텍처별 **서명(signature)** 이 함께 존재  

### 앱 구조의 시각적 개요
- 다이어그램에서 **연노란색**은 필수 또는 거의 모든 앱에 존재하는 구성 요소  
- **녹색**은 App Store 배포 앱에서만 존재하는 항목, **파란색**은 선택적 공증 티켓을 의미  
- 추가적으로 **Automator 워크플로우, 스크립트** 등 부가 요소가 포함될 수 있음  
- 전체적으로 macOS 앱은 **자급적·보안 중심 구조**로 진화해 왔음

## Comments



### Comment 47419

- Author: neo
- Created: 2025-12-09T04:33:02+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=46181268) 
- 파란색으로 표시된 부분은 **notarisation ticket**(공증 티켓)인데, 사실상 선택 사항이 아님  
  공증되지 않은 앱은 사용자 입장에서 너무 불편해서 결국 연 $99의 **Apple 개발자 등록비**를 내야 함  
  개인용으로만 빌드하고 실행한다면 괜찮지만, 배포용이라면 macOS가 경고창을 띄워 앱이 망가진 것처럼 보임  
  예전엔 우클릭으로 실행할 수 있었지만, 이제는 시스템 설정까지 들어가야 허용 가능함  
  관련 스크린샷은 [Apple 지원 문서](https://support.apple.com/en-us/102445)와 [개발자 뉴스](https://developer.apple.com/news/?id=saqachfa)에서 볼 수 있음  
  나는 Apple의 보안 철학은 좋아하지만, **App Store 외부 앱의 공증 제도**는 모든 당사자에게 손해라고 생각함  
  실제로 공증이 보안 문제를 막은 사례를 찾지 못했음  

  - macOS 공증이 귀찮다고 생각했는데, **Windows 배포**를 해보니 그건 더 심했음  
    Windows Defender의 신뢰를 얻으려면 인증서를 사야 하고, 회사와 개인 모두 **깊은 신원 검증**을 거쳐야 함  
    하드웨어 토큰으로 서명해야 해서 한 명만 릴리스를 배포할 수 있음  
    게다가 인증 기관이 임의로 키를 잠글 수도 있어서, 보안 패치를 내야 할 때 막히면 끔찍함  
    이런 점에서 macOS 생태계가 훨씬 낫다고 느낌  

  - 나는 여러 플랫폼으로 컴파일되는 **프로그래밍 언어**를 개발 중인데, 서명과 공증은 이 과정과 전혀 맞지 않음  
    이런 서명 제도는 **통제 수단**일 뿐이며, Epic 사례처럼 남용될 위험이 있음  
    서명되지 않은 바이너리를 합리적으로 실행할 수 없으면 그 플랫폼은 닫힌 것으로 간주하고 지원하지 않음  
    iOS나 Android 같은 폐쇄형 플랫폼은 **PWA**로 어느 정도 대체 가능함  
    다만 Google이 자가 서명 앱 실행을 계속 허용할지 신뢰가 약해진 상태임  

  - Apple이 App Store 외부 앱의 인증서를 취소한 사례는 두 번밖에 모름  
    하나는 Facebook의 **Research App**, 다른 하나는 Google의 **Screenwise Meter**였음  
    둘 다 청소년을 대상으로 한 스파이웨어 성격의 앱이었고, 인증서 취소로 내부 도구까지 마비됨  
    이후 Screenwise Meter는 App Store에 다시 올라온 것으로 보임  
    관련 기사: [Wired](https://www.wired.com/story/facebook-research-app-root-certificate/), [EFF](https://www.eff.org/deeplinks/2019/02/google-screenwise-unwise-trade-all-your-privacy-cash)  

  - 내 앱 폴더의 절반 정도는 공증되지 않았는데, 실제로는 **별 문제 없음**  

  - 공증 후 **stapled ticket**(첨부 티켓)은 선택 사항임  
    티켓을 첨부하지 않으면 사용자가 인터넷 연결로 공증 상태를 확인해야 함  

- [AppBundler.jl](https://github.com/PeaceFounder/AppBundler.jl)을 개발하면서 macOS 앱 구조에 불만이 많음  
  **Frameworks 폴더 구조 강제**가 보기엔 깔끔하지만, 실제로는 번들링이 번거로워 Libraries 폴더로 우회 중임  
  가장 큰 문제는 **코드 서명**임 — 모든 바이너리에 서명을 붙이는 건 낭비처럼 느껴짐  
  파일 해시를 모아 한 번만 서명하면 될 일을 왜 이렇게 복잡하게 만드는지 이해하기 어려움  
  또한 **entitlements**가 런처 바이너리에만 붙는 것도 비효율적임  
  공증 기준이 시간이 지나면서 강화되기 때문에, 나중에 갑자기 앱이 통과하지 못할 수도 있음  

- Tauri 앱을 서명·공증하려고 Apple Developer Program에 가입했는데, **3주째 실패 중**임  
  Mac이 없어 GitHub Actions로 시도했지만, 첫 공증은 오래 걸리는 게 흔하다고 함  
  GitHub 비용만 $100 가까이 썼는데 아직도 공증이 안 됨  
  Apple 지원팀은 Mac이 없고 Tauri를 쓴다는 이유로 도움을 거부함  
  **공증 API 인증 과정**도 악몽 수준임 — PKCS8로 JWT를 만들어야 하는데 문서가 거의 없어 직접 Node 프로그램을 짜야 했음  
  지금까지 겪은 최악의 **개발자 경험(DX)** 이었음  

  - 중고 Mac mini를 $150에 사서 그걸로 서명하라는 조언을 받음  
    Apple 하드웨어 없이 이걸 해결하려는 건 **시간 낭비**라고 함  

- 첫 번째 OS 스크린샷을 보고 마음이 철렁했음  
  예전엔 **실용적이고 깔끔한 UI**였는데, 요즘은 둥근 모서리와 거품 같은 아이콘으로 공간만 낭비됨  
  그래도 Mac 하드웨어 품질이 좋아서 ThinkPad로 못 옮기고 있음  

  - 둥근 모서리는 오히려 **인간 시각에 유리한 기능**임  
    각진 모서리가 시각 피로를 유발한다는 연구가 있음  
    관련 글: [Round Rects Are Everywhere](https://folklore.org/Round_Rects_Are_Everywhere.html)  

  - 나도 최신 macOS는 별로지만, 그 스크린샷도 완벽하진 않음  
    선이 너무 많고 색이 부족해서 시선이 분산됨  
    개인적으로는 **Leopard 시절의 Aqua UI**가 정보 밀도와 시각적 깊이의 균형이 좋았음  

  - 픽셀 비율로 보면 예전 UI가 오히려 공간을 더 많이 차지함  
    5K 해상도 기준으로는 현대 MacBook Pro 쪽이 효율적임  
    고전 Mac도 약간의 둥근 모서리를 이미 가지고 있었음  
    참고: [Infinite Mac](https://infinitemac.org/)  

  - 컴퓨터는 업무용만이 아니라 **즐거움을 위한 도구**이기도 함  
    다만 요즘 UI는 실용성에서 너무 멀어진 느낌임  

  - 화면의 대부분이 쓸모없는 101101 같은 정보라서 실용적이라 보기 어려움  

- macOS에서 명령줄 도구 실행 시 **launchd**가 실행 주체라는 말은 틀림  
  실제로는 다른 UNIX 시스템처럼 쉘에서 **fork/spawn**으로 실행됨  

- NeXTSTEP의 번들 시스템이 **Java의 JAR 파일** 설계에 영감을 줬음  
  - 하지만 JAR은 단순히 **ZIP 파일에 확장자만 바꾼 것**임  

- 클래식 Mac OS의 Power Mac 앱은 **PPC 코드가 데이터 포크에 저장**되었음  
  CFM-68K 바이너리도 마찬가지였고, CODE 리소스를 쓴 건 구형 68K 코드뿐이었음  

- 예전 **ResEdit**으로 앱을 수정하던 시절이 즐거웠던 기억이 있음  

- 마지막 다이어그램처럼 **관료주의가 폭발**하는 건 좋은 신호가 아님  
  macOS 26으로 “업그레이드”할 이유가 더 줄어듦  
  - 앱 번들에 폴더가 몇 개 늘었다고 호들갑 떨 필요는 없다는 반응도 있음  

- 지금 구조가 macOS의 “표준”이긴 하지만, **유일한 방법은 아님**  
  RPATH를 잘 설정하면 임의의 하위 폴더에 라이브러리를 넣어도 공증 통과 가능함  
  예를 들어 AppName.App/Contents/Libraries 경로도 작동함  
  다만 이 방식의 실질적 이점은 거의 없고, 내 시스템의 100여 개 앱 중 /Libraries 폴더를 쓰는 건 하나도 없음  
  - iOS는 이 부분이 훨씬 **엄격하고 불명확**함  
    .dylib 대신 반드시 .framework 형식을 써야 하고, 이건 문서화되지 않은 규칙임  
    제출 시 자동으로 감지되어 거절당할 수 있음
