문서 검색

Mac App Store (macOS)

Flutter macOS 앱을 Mac App Store 에 올리는 절차를 App Sandbox · 인증서 · flutter build macos · 서명과 패키징 · 업로드 · 심사 제출 순서로 안내하고, Developer ID 직접 배포(공증)와의 차이를 설명합니다.

마지막 확인:
목차

Flutter macOS 앱을 Mac App Store 로 내는 절차입니다. Apple 계정 하나로 App Store 와 Mac App Store 에 모두 올릴 수 있고, 스토어 등록정보 · 앱이 수집하는 개인정보 · 수출 규정 · 연령 등급 · 심사 제출 · 출시 방식은 App Store (iOS · iPadOS) 편의 10~14단계와 같습니다. 이 페이지는 Mac 에서 달라지는 부분 — App Sandbox, 인증서, 프로비저닝 프로필, .pkg 패키지, 업로드 — 에 집중합니다.

참고

Cocode IDE 로 만든 프로젝트도 Flutter 프로젝트라 같은 절차를 따릅니다. 다만 프로젝트에 macos/ 폴더가 있는지, 서명과 버전 설정을 CI 가 대신하는지는 프로젝트마다 다를 수 있으니 프로젝트의 README 와 CI 설정을 확인하세요.

주의

업로드 요건 · 인증서 이름 · 콘솔 메뉴 이름은 Apple 이 바꿀 수 있습니다. 이 페이지의 수치는 「마지막 확인」 날짜 기준이고, 다르면 Apple 의 공식 문서가 우선합니다. App Store Connect 화면은 로그인이 필요해 직접 확인하지 못했으므로, 메뉴와 버튼 이름 · 각 단계의 성공 판정(화면에 보이는 상태)은 Apple 도움말의 설명을 따랐습니다. 이름은 확인한 범위에서 한국어판 도움말의 표기를 「한글(영문)」으로 적었고, 확인하지 못한 이름은 영문으로 적었습니다(역할 이름은 영문으로 통일했습니다).

준비물

  • 끝낸 공통 준비 — 개발자 계정, 식별자와 버전, 아이콘 · 스플래시 · 스크린샷(Mac 스크린샷은 16:10 비율의 규격 크기), 개인정보와 권한.
  • Mac 과 Xcode — Flutter 3.47 이 지원하는 macOS 는 Monterey(12) 이상입니다(지원 플랫폼 표). Apple 의 업로드 요건 표는 iOS 앱과 macOS 앱의 Xcode 요건을 따로 적습니다(macOS 앱은 「Xcode 6 or later」). 2026-04-28 부터의 Xcode 26 요건 문장에는 macOS 가 나열되지 않습니다(2026-10-09 확인).
  • Mac 에서 시험 — 릴리스 .app 을 직접 실행해 네트워크 · 파일 접근이 샌드박스 안에서 되는지 확인합니다(제출 전 체크리스트).
  • (직접 서명할 때) 인증서와 프로필 — 아래 3단계를 보세요. Apple 도움말의 「필요한 역할」 기준으로 배포 인증서는 Account Holder 또는 Admin 이 만듭니다.

Developer ID 직접 배포와의 차이

Mac 앱은 Mac App Store 로 내거나, Developer ID 로 서명해 스토어 밖(웹사이트 등)에서 직접 배포할 수 있습니다. Flutter 문서도 두 경로를 모두 안내하며, 이 가이드는 Mac App Store 경로입니다. 둘의 차이는 다음과 같습니다.

항목 Mac App Store (이 가이드) Developer ID 직접 배포
배포와 업데이트 Apple 이 호스팅하고 업데이트도 Mac App Store 로만 배포해야 합니다(심사 지침 2.4.5(vii)) 개발자가 직접 관리합니다
App Sandbox(샌드박스) 필수(Required) 권장(Recommended). 공증에는 Hardened Runtime 이 필수이고 샌드박스는 선택입니다
서명 인증서 앱은 「Apple 배포(Apple Distribution)」(인증서 목록에는 「Mac 앱 배포(Mac App Distribution)」도 있음), 설치 패키지는 「Mac 설치 프로그램 배포(Mac Installer Distribution)」 앱은 「Developer ID 애플리케이션(Developer ID Application)」, 설치 패키지는 「Developer ID 설치 프로그램(Developer ID Installer)」
검토 App Review 심사 공증(notarization) — 악성 콘텐츠와 서명 문제를 자동 검사하며 App Review 가 아닙니다
공증 필요 없습니다. 스토어 제출 과정에 동등한 보안 점검이 있습니다 필요합니다(macOS 10.15 부터 2019-06-01 이후 빌드). xcrun notarytool submit 으로 올리고, 끝나면 티켓을 stapler 로 파일에 붙입니다
앱 내 구입 · Game Center 사용할 수 있습니다 사용할 수 없습니다
Xcode Organizer 의 배포 방식 TestFlight & App Store, 또는 Custom → App Store Connect Direct Distribution, 또는 Custom → Developer ID

참고

두 경로를 함께 낼 때, codesign 이 적용하는 기본 designated requirement 로 서명한 두 변형(방법 B)은 개인정보 보호 리소스(마이크 등) 접근 권한을 서로 공유하지 못합니다. Xcode 는 서로 호환되는 designated requirement 로 서명해 이 한계를 피합니다. 직접 서명하면서 공유하려면 TN3127 의 방법을 따르세요.

프로젝트에서 바꿀 항목

아래 파일 위치와 기본값은 flutter create 로 만든 Flutter 3.47.6 기본 프로젝트에서 확인한 것입니다(2026-10-09). 프로젝트마다 다를 수 있으니 직접 열어 확인하세요.

항목 어디서 바꾸나 기본값과 메모
앱 이름 macos/Runner/Configs/AppInfo.xcconfig 의 PRODUCT_NAME 기본은 프로젝트 이름이며 .app 파일 이름과 기본 창 제목이 됩니다. App Store Connect 의 앱 「이름」과는 따로 입력합니다
번들 ID 같은 파일의 PRODUCT_BUNDLE_IDENTIFIER 기본은 com.example.<프로젝트 이름을 lowerCamelCase 로 바꾼 값> 입니다(예: my_app → com.example.myApp). App Store Connect 에 첫 빌드를 올린 뒤에는 번들 ID 를 바꿀 수 없으니 올리기 전에 정하세요. iOS 앱과 한 앱으로 판매하려면 ios/ 와 같은 번들 ID 를 씁니다
저작권 같은 파일의 PRODUCT_COPYRIGHT Info.plist 의 NSHumanReadableCopyright 가 받아 씁니다. macOS 앱은 업로드 전에 이 키를 설정해야 하고, 기본값은 com.example 이 들어간 자리표시자입니다
앱 카테고리 Xcode 에서 Runner 타깃 → General → Identity → App Category 기본 Info.plist 에는 없습니다. Flutter 문서는 「none」일 수 없다고 하고, App Store Connect 의 기본 카테고리와 같거나 가까운 것으로 고릅니다. Xcode 를 열 수 없는 CI 라면 macos/Runner/Info.plist 에 LSApplicationCategoryType 키를 직접 넣습니다
버전 · 빌드 번호 pubspec.yaml 의 version: Mac 앱의 빌드 번호는 앱의 모든 버전에 걸쳐 계속 올라가야 합니다. 식별자와 버전
최소 macOS 버전 Runner 타깃 → General → Deployment Info (프로젝트 파일에서는 MACOSX_DEPLOYMENT_TARGET) 기본은 12.0 이고 Info.plist 의 LSMinimumSystemVersion 이 받아 씁니다
샌드박스 · entitlements macos/Runner/Release.entitlements(릴리스) · macos/Runner/DebugProfile.entitlements(디버그 · 프로파일) 기본 릴리스 파일에는 com.apple.security.app-sandbox 만 있고, 기본 DebugProfile.entitlements 에는 app-sandbox · cs.allow-jit · network.server 만 있습니다. 네트워크 요청을 하면 두 파일에 com.apple.security.network.client 를 똑같이 더해야 합니다
권한 사유 문구 macos/Runner/Info.plist 의 NS…UsageDescription 키 기본 템플릿에는 없습니다. 카메라 · 마이크처럼 보호된 리소스는 사유 문구와 샌드박스 entitlement 가 모두 필요하고, 사용자가 대화 상자로 고르는 파일은 files.user-selected.* entitlement 를 씁니다. 개인정보와 권한
서명 · 팀 Runner 타깃 → Signing & Capabilities → Automatically manage signing · Team 기본은 자동 서명입니다
수출 규정 키 macos/Runner/Info.plist 의 ITSAppUsesNonExemptEncryption 기본 템플릿에는 없습니다. 앱이 암호화를 쓰지 않거나 면제되는 암호화만 쓸 때의 설정은 iOS 편 11단계를 보세요
아이콘 macos/Runner/Assets.xcassets 의 AppIcon 아이콘 · 스플래시 · 스크린샷

단계

앱 등록과 서명 준비

  1. 앱 레코드를 정합니다. 계약 상태 확인 · 번들 ID 등록 · 앱 레코드 만들기는 App Store (iOS · iPadOS) 편의 1~3단계와 같고, 플랫폼으로 macOS 를 고릅니다. iOS 앱과 한 번의 구입으로 함께 팔지에 따라 둘 중 하나를 고릅니다.

    • iOS 앱과 한 앱으로 판매(유니버설 구입) — 기존 iOS 앱 레코드의 사이드바에서 「플랫폼 추가(Add Platform)」로 macOS 를 더합니다. Xcode 11.4 부터는 한 App ID 로 iOS · macOS 앱을 모두 빌드할 수 있습니다. macOS 앱은 같은 Apple ID · SKU · 번들 ID 를 쓰고, macos/ 의 번들 ID 를 iOS 와 같게 맞춥니다. 버전 번호와 빌드 번호는 iOS 와 달라도 됩니다. 플랫폼을 추가하면 기존 플랫폼 버전의 메타데이터가 새 플랫폼 버전으로 옮겨지지만 홍보용 텍스트 · 설명 · 스크린샷은 옮겨지지 않습니다. 아직 앱 레코드가 없다면 「신규 앱」 대화창에서 iOS 와 macOS 를 함께 선택해 한 레코드로 만들 수도 있습니다.
    • macOS 만 새 앱 레코드 — iOS 편 3단계처럼 「신규 앱」에서 macOS 를 고릅니다.

    주의

    Apple 은 플랫폼별로 따로 만든 앱 레코드는 합칠 수 없다고 안내합니다. 또 App Review 가 두 플랫폼 버전을 승인하면 유니버설 구입이 되고, 그 뒤에는 앱 레코드에서 플랫폼 버전 하나만 뺄 수 없습니다. 레코드를 만들기 전에 정하세요.

    성공 판정 — 앱 레코드에서 macOS 버전 페이지를 열 수 있습니다.

  2. 샌드박스와 entitlements 를 맞춥니다. Mac App Store 로 내려면 App Sandbox 를 켜야 하고(심사 지침 2.4.5(i)), Flutter macOS 빌드는 기본으로 샌드박스가 적용됩니다. 샌드박스 앱은 네트워크 · 카메라 · 파일 접근 같은 권한을 entitlement 로 밝혀야 하며, 밝히지 않으면 시스템이 런타임에 막습니다. 그래서 macos/Runner/Release.entitlements 와 macos/Runner/DebugProfile.entitlements 두 파일에 앱이 쓰는 권한을 똑같이 더합니다. Flutter 문서는 특별한 이유가 없으면 두 파일을 똑같이 고치라고 하며, 기본 DebugProfile.entitlements 에도 network.client 가 없어 디버그 실행에서도 네트워크 요청이 막힙니다(Flutter 3.47.6 에서 확인).

    xml
    <key>com.apple.security.network.client</key>
    <true/>
    

    com.apple.security.network.client 는 밖으로 나가는 네트워크 연결을 열어 주며, Flutter 문서는 네트워크 요청을 하는 앱이라면 반드시 더하라고 합니다. 파일 선택기(file_selector)를 쓰면 com.apple.security.files.user-selected.read-only 나 read-write 가 필요합니다. 들어오는 연결을 받아야 하면 com.apple.security.network.server 를 릴리스 파일에도 더합니다(기본은 디버그 · 프로파일에만 켜져 있습니다). 파일을 고칠 때는 Xcode 의 capabilities 화면 대신 파일을 직접 편집하라고 Flutter 문서가 권합니다. 샌드박스의 임시 예외(temporary exception) entitlement 를 쓰는 앱은 그 entitlement 마다 정보를 Apple 에 제공해야 합니다(Apple 도움말 「App Sandbox 정보」). 성공 판정은 릴리스 빌드로 만든 앱에서 네트워크 요청과 파일 열기가 동작하는 것입니다.

  3. 서명을 정합니다. Xcode 로 올린다면(아래 방법 A) open macos/Runner.xcworkspace 로 Runner 타깃의 Signing & Capabilities 에서 Automatically manage signing 을 켜고 Team 을 고르면 됩니다. Apple 은 자동 서명으로 올리면 Xcode 가 배포 프로비저닝 프로필을 관리한다고 안내합니다. 명령줄로 직접 서명한다면(방법 B) 아래를 준비합니다.

    준비할 것 이름과 만드는 곳
    앱 서명 인증서 Apple 의 Mac 배포 서명 문서는 Mac App Store 앱에 「Apple Distribution」 서명 ID(Apple Distribution: <팀 이름> (<팀 ID>))를 쓰라고 합니다. 인증서 개요에는 「Mac App Distribution」(Mac App Store 에 제출하기 전에 Mac 앱에 서명)도 나열됩니다
    설치 패키지 서명 인증서 「Mac Installer Distribution」. 키체인 이름은 3rd Party Mac Developer Installer: <팀 ID> 로 보입니다
    프로비저닝 프로필 Certificates, Identifiers & Profiles 의 Profiles → 추가 버튼(+) → Distribution 에서 「Mac App Store Connect」(Mac 앱용) → 번들 ID 와 일치하는 App ID → 배포 인증서 → 이름 → Generate → Download. 파일 확장자는 .provisionprofile 입니다. 프로필에는 배포 인증서가 하나만 들어가니 앱 서명에 쓸 인증서(Apple Distribution 또는 Mac App Distribution)를 그대로 고르세요

    Apple 도움말의 「필요한 역할」은 Account Holder 또는 Admin 이고, 배포 인증서는 Developer ID 인증서를 뺀 종류마다 팀당 하나만 허용됩니다. 인증서를 만들 때 필요한 서명 요청(CSR)은 iOS 편 4단계와 같습니다. 성공 판정 — 방법 A 라면 Signing & Capabilities 에 서명 오류가 없습니다. 방법 B 라면 서명 인증서 둘과 프로필 파일(.provisionprofile)이 준비됐습니다.

빌드와 업로드

  1. flutter build macos 로 릴리스 빌드를 만듭니다.

    bash
    flutter build macos --build-name=1.0.0 --build-number=1
    

    기본이 릴리스 모드이고, 결과 앱은 build/macos/Build/Products/Release/<앱 이름>.app 에 생깁니다. 이 앱은 ad hoc 서명이라(Flutter 3.47.6 에서 확인) Mac App Store 에 내려면 Apple 이 요구하는 배포용 서명(distribution-signed)을 입혀야 합니다. 아래 방법 A 나 B 로 입힙니다. Dart 코드를 난독화하려면 --obfuscate --split-debug-info=<심볼 폴더> 를 함께 줍니다. 성공 판정은 명령이 Built build/macos/Build/Products/Release/….app 을 출력하는 것입니다.

  2. 방법 A(권장) — Xcode 로 보관(Archive)하고 올립니다. Flutter 문서가 안내하는 경로입니다. open macos/Runner.xcworkspace 로 연 뒤 다음을 합니다.

    1. Runner 타깃 General → Identity 에서 App Category · Bundle Identifier · 버전과 빌드 번호를 확인합니다.
    2. 메뉴 Product → Archive 로 아카이브를 만듭니다. Archives organizer 에 나타납니다.
    3. 아카이브를 골라 Validate App 으로 제출 전 자동 검증을 합니다. 문제가 있으면 고쳐 다시 빌드합니다.
    4. Distribute App 에서 「TestFlight & App Store」(기본 권장 설정)를 고르거나, Custom 에서 「App Store Connect」를 고르고 대상(destination)으로 업로드를 고릅니다. Xcode 가 처리 · 패키징 · 업로드를 시작합니다.

    Mac 앱에는 Distribute App 의 Release Testing 과 Enterprise 방식은 쓸 수 없습니다. 성공 판정은 Xcode 가 업로드를 마치고 App Store Connect 앱의 빌드 목록에 빌드가 나타나는 것입니다.

  3. 방법 B — 명령줄로 서명하고 .pkg 를 만들어 올립니다. CI 처럼 Xcode 화면을 쓸 수 없을 때의 경로입니다. Mac App Store 는 앱을 설치 패키지(.pkg) 로 받습니다.

    주의

    이 경로는 서명 · entitlements · 프로파일을 직접 책임집니다. Apple 이 Flutter 앱용으로 완성된 명령 한 벌을 주지는 않아서, 아래는 Apple 문서의 규칙을 순서대로 옮긴 것입니다. 같은 일을 하는 CI 예시는 Flutter 문서의 「Create a build archive with Codemagic CLI tools」 절에 있습니다(서드파티 도구를 씁니다). 막히면 방법 A 를 쓰세요.

    1. entitlements 파일을 준비합니다. 배포용 .app 에 넣을 entitlements 를 만듭니다. Apple 은 Xcode 로 개발 서명한 앱에서 codesign -d --entitlements - --xml <앱> | plutil -convert xml1 -o - - 로 entitlements 를 출력해 배포용 파일의 바탕으로 쓸 수 있다고 안내하고, 디버거 연결을 허용하는 com.apple.security.get-task-allow 는 배포용에는 거의 쓰지 않는다고 합니다. Flutter 가 만든 릴리스 .app 에서 이렇게 뽑으면 com.apple.security.app-sandbox 와 함께 com.apple.security.get-task-allow 가 들어 있습니다(Flutter 3.47.6 에서 확인). 배포용 파일에서는 이 키를 빼는 쪽이 Apple 안내에 맞으니, 2단계에서 정한 앱 권한만 남기세요. 파일은 표준 XML 속성 목록(LF 줄바꿈, 주석 없음, BOM 없음)이어야 합니다.

    2. 배포 프로비저닝 프로필을 앱 번들에 넣습니다. 3단계에서 받은 프로필을 <앱>.app/Contents/embedded.provisionprofile 로 복사합니다. 앱 번들을 고치면 서명이 깨지므로 아래 서명 전에 합니다. TestFlight 대상이 되려면 프로비저닝 프로필에 application identifier 가 있어야 합니다.

    3. com.apple.quarantine 확장 속성을 없앱니다. 프로필을 복사한 뒤, 서명과 .pkg 만들기 전에 합니다. macOS 에서 cp · ditto 로 복사하면 원본의 com.apple.quarantine 속성이 복사본에도 붙으므로(macOS 에서 확인) 내려받은 프로필의 속성이 앱 번들로 따라 들어올 수 있습니다. xattr -lr "<앱>.app" 으로 com.apple.quarantine 이 있는지 보고, 있으면 xattr -dr com.apple.quarantine "<앱>.app" 로 지웁니다. Apple 은 2025-02-18 부터 앱 안의 모든 파일에서 이 속성을 지워야 App Store Connect 에 올릴 수 있다고 안내합니다. .pkg 를 만든 뒤에 지우면 이미 만든 .pkg 안에는 속성이 남으니(macOS 에서 확인) 그때는 .pkg 를 다시 만드세요.

    4. 안쪽 코드부터 서명합니다. 번들 안의 프레임워크 등 모든 실행 코드를 안쪽부터 서명하고 마지막에 .app 을 서명합니다. 이미 서명된 코드를 다시 서명하려면 -f, 메인 실행 파일에는 --entitlements 를 더합니다. --deep 은 쓰지 말라고 Apple 이 권고합니다. 빌드 산출물 .app 을 다른 폴더로 옮겨 서명한다면 cp -R 대신 ditto 를 쓰세요. ditto 는 Mac 프레임워크 구조에 중요한 심볼릭 링크를 보존합니다.

      bash
      codesign -s "Apple Distribution: <팀 이름> (<팀 ID>)" -f \
        "<앱>.app/Contents/Frameworks/<프레임워크>.framework"
      codesign -s "Apple Distribution: <팀 이름> (<팀 ID>)" -f \
        --entitlements "<배포용>.entitlements" "<앱>.app"
      

      예시의 서명 ID 이름은 Apple 문서의 표기입니다. 실제 이름은 security find-identity -v 출력에서 그대로 복사하고, 같은 이름이 여러 개면 이름 대신 그 줄의 SHA-1 해시로 지정하세요. 성공 판정 — codesign --verify --deep --strict -vv "<앱>.app" 가 valid on disk 와 satisfies its Designated Requirement 를 출력합니다(서명을 만들 때는 --deep 을 쓰지 말라는 것이지 검증에는 써도 됩니다).

    5. .pkg 를 만듭니다. 앱 하나뿐이면 productbuild 의 가장 단순한 형태가 Mac App Store 제출에 충분하다고 Apple 이 안내합니다. Mac App Store 용 패키지는 --component 방식만 써야 합니다(man productbuild).

      bash
      productbuild --sign "3rd Party Mac Developer Installer: <팀 ID>" \
        --component "<앱>.app" /Applications "<앱>.pkg"
      

      설치 패키지 서명 ID 는 코드 서명 ID 와 달라서 security find-identity -v 로 찾아야 합니다(-p codesigning 으로 거르면 나오지 않습니다). 성공 판정 — pkgutil --check-signature "<앱>.pkg" 가 설치 패키지 서명 인증서를 보여 줍니다.

    6. 업로드합니다. Apple 은 서명한 설치 패키지를 altool 명령줄 도구나 Transporter 앱으로 제출하라고 안내합니다. Transporter 는 Mac App Store 에서 받는 macOS 앱입니다. 명령줄은 iOS 편 7단계와 같은 방식(API 키 또는 사용자 이름과 앱 암호)으로 인증하고, 형식은 다음과 같습니다.

      bash
      xcrun altool --upload-package "<앱>.pkg" \
        --apple-id <앱의 Apple ID> --bundle-id <번들 ID> \
        --bundle-short-version-string <버전> --bundle-version <빌드 번호> \
        --apiKey <키 ID> --apiIssuer <발급자 ID>
      

      --upload-app 형식의 deprecated 안내와 옵션 이름 확인은 iOS 편 7단계의 알림을 따르세요. -t(플랫폼)는 선택 사항이며(altool 가이드) 값 이름이 가이드(osx · ios · appletvos)와 Xcode 27.0 의 altool --help(macos · ios · appletvos · visionos)에서 다르니 쓰려면 도움말로 확인하세요.

    성공 판정 — 방법 B 의 각 명령이 오류 없이 끝나고, 업로드 도구가 끝난 뒤 7단계에서 빌드가 나타납니다.

시험과 출시

  1. 처리를 기다리고 TestFlight 로 시험합니다. 처리가 끝나면 이메일이 오고 빌드가 나타납니다. TestFlight 는 Mac 앱도 지원하며, Mac 용 TestFlight 를 쓰려면 macOS 앱을 Xcode 13 이상으로 빌드하라고 Apple 이 안내합니다. 빌드가 TestFlight 대상이 되려면 프로비저닝 프로필 안에 application identifier 가 있어야 합니다. 내부 · 외부 테스트 방법은 iOS 편 8~9단계와 같습니다. App Store 로 내기 전에 Apple 이 공증한 빌드를 직접 나눠 줘 시험할 수도 있습니다. 성공 판정 — 빌드가 앱의 TestFlight 탭에 나타나고 테스터가 설치해 실행합니다.
  2. 심사에 제출하고 출시합니다. iOS 편 10~14단계와 같은 항목을 채우고 빌드를 골라 제출합니다. 이름 · 연령 등급처럼 플랫폼이 함께 쓰는 앱 정보는 앱 레코드에 한 번만 채우고, 지원 URL · 저작권 · 앱 심사 정보 · 버전 출시 설정 같은 버전 정보는 macOS 버전 페이지에서 채웁니다(Apple 의 필수 속성 표). 플랫폼마다 앱 버전을 따로 제출하고, 한 플랫폼 버전의 상태가 다른 플랫폼 버전의 상태에 영향을 주지 않습니다. 수동 출시를 골랐다면 macOS 버전도 따로 「이 버전 출시」를 눌러야 합니다. 성공 판정 — macOS 버전의 상태가 「심사 대기 중」으로 바뀝니다.

확인

  • 샌드박스: 릴리스 .app 에서 codesign -d --entitlements - <앱> 출력에 com.apple.security.app-sandbox 가 true 로 있습니다. 앱을 실행한 뒤 Activity Monitor 의 View → Columns → Sandbox 열에서 앱이 「Yes」입니다.
  • 권한: 릴리스 빌드에서 네트워크 요청 · 파일 열기 같은 기능이 동작합니다.
  • 업로드: 앱의 빌드 목록(TestFlight 탭)에 macOS 빌드가 나타나고 빌드 번호가 방금 올린 값과 같습니다.
  • 제출: macOS 버전의 상태가 「심사 대기 중」으로 바뀌었습니다. 심사가 시작되면 「심사 중」이 됩니다.
  • 출시: 상태가 「배포 준비됨(Ready for Distribution)」이고 Mac App Store 에서 앱 제품 페이지가 열립니다.

자주 겪는 문제

네트워크 요청이 「Operation not permitted」 오류로 실패합니다

샌드박스 앱은 com.apple.security.network.client entitlement 가 없으면 SocketException: Connection failed (OS Error: Operation not permitted, errno = 1) 같은 메시지로 요청이 막힌다고 Flutter 문서가 예시합니다. 기본 템플릿은 DebugProfile.entitlements 에도 이 키가 없어 디버그 실행에서도 같은 오류가 납니다(Flutter 3.47.6 에서 확인). 릴리스 빌드에서만 실패한다면 DebugProfile.entitlements 에만 키를 더하고 Release.entitlements 는 놓친 경우입니다. 두 파일에 위 2단계의 키를 똑같이 더하세요. Flutter 문서 본문은 파일 이름을 Runner-Release.entitlements 처럼 적지만 Flutter 3.47.6 기본 템플릿의 이름은 Release.entitlements 입니다. 프로젝트의 macos/Runner/ 폴더에서 실제 *.entitlements 이름을 확인하세요.

업로드가 quarantine 속성 때문에 거부됩니다

Apple 은 macOS 앱에 com.apple.quarantine 확장 파일 속성이 있으면 안 되고, 2025-02-18 부터 앱 안의 모든 파일에서 이 속성을 지워야 App Store Connect 에 올릴 수 있다고 안내합니다. 인터넷에서 받은 파일(예: 내려받은 프로비저닝 프로필)이 앱 번들에 섞였는지 확인하세요. macOS 에 포함된 xattr 도움말 기준으로 xattr -lr <앱>.app 은 확장 속성을 나열하고, xattr -dr com.apple.quarantine <앱>.app 은 그 속성을 지웁니다. 속성을 지운 뒤에는 .pkg 를 다시 만들어 올리세요. 이미 만든 .pkg 안의 앱에는 속성이 남아 있습니다(macOS 에서 확인).

앱 카테고리는 어디서 정하나요?

Mac 앱은 App Store Connect 의 카테고리와 별도로 Xcode 프로젝트에서도 카테고리를 정합니다. Runner 타깃의 General → Identity → App Category 에서 App Store Connect 의 기본 카테고리와 같거나 가까운 것으로 고르세요. Flutter 문서는 이 값이 none 일 수 없다고 하고, 보관된(retired) Apple 문서는 Mac App Store 에 제출하려면 Info.plist 최상위에 LSApplicationCategoryType 키로 카테고리를 정의해야 한다고 안내합니다(값은 public.app-category.business 같은 UTI). Xcode 를 열 수 없는 CI 라면 macos/Runner/Info.plist 에 이 키를 직접 넣습니다.

TestFlight 에서 빌드를 쓸 수 없다고 나옵니다

프로비저닝 프로필에 application identifier 가 빠진 빌드는 TestFlight 에서 쓸 수 없고 「테스트할 버전이 준비되지 않음(Not Available for Testing)」으로 보입니다. 식별자가 포함된 새 빌드를 올려야 합니다. 자동 서명이면 Xcode 가 배포 프로비저닝 프로필을 관리해 주고, 수동 서명이면 위 방법 B 의 2번처럼 직접 넣습니다.

심사에서 2.4.5 (Mac App Store 요구 사항) 로 거절됐습니다

Mac App Store 앱에는 심사 지침 2.4.5 의 추가 요구 사항이 있습니다.

  • (i) 적절히 샌드박스되어야 하고 macOS 파일 시스템 문서를 따라야 합니다.
  • (ii) Xcode 가 제공하는 기술로 패키징 · 제출해야 하고, 서드파티 설치 프로그램은 쓸 수 없습니다. 독립적인 단일 앱 설치 번들이어야 하고 공유 위치에 코드나 리소스를 설치할 수 없습니다.
  • (iii) 동의 없이 시동 · 로그인 때 자동 실행되거나 코드를 돌리면 안 되고, 사용자가 앱을 종료한 뒤에도 동의 없이 계속 실행되는 프로세스를 만들면 안 됩니다. 또 Dock 에 아이콘을 자동으로 추가하거나 데스크탑에 바로 가기를 남기지 않아야 합니다.
  • (iv) 심사 때 본 것과 달리 기능을 바꾸는 독립 앱 · kext · 추가 코드 · 리소스를 내려받아 설치하면 안 됩니다.
  • (v) 루트 권한 상승을 요청하거나 setuid 속성을 쓰면 안 됩니다.
  • (vi) 실행 시 사용권 화면을 보이거나 라이선스 키를 요구하거나 자체 복사 방지를 구현하면 안 됩니다.
  • (vii) 업데이트는 Mac App Store 로만 배포해야 합니다. 다른 업데이트 방식은 허용되지 않습니다.
  • (viii) 현재 출시된 OS 에서 실행되어야 하고, deprecated 되었거나 선택 설치되는 기술(예: Java)을 쓰면 안 됩니다.
  • (ix) 모든 언어와 현지화를 하나의 앱 번들 안에 담아야 합니다.

그 밖의 거절 사유(2.1 · 4.x · 5.1.1)와 답하는 방법은 App Store (iOS · iPadOS) 편의 「자주 겪는 문제」와 같습니다. 스토어별 사유와 번호, 재제출 방법은 심사 거절 대응에도 모았습니다.

한 앱 레코드로 합칠 수 있나요? 이미 iOS 와 macOS 를 따로 냈습니다

Apple 은 플랫폼별로 따로 만든 앱 레코드는 합칠 수 없다고 안내합니다. 유니버설 구입을 하려면 한 레코드만 남기고 나머지를 판매 중단한 뒤 그 레코드에 플랫폼을 더해야 하는데, 판매 중단한 앱의 원래 제품 페이지는 쓸 수 없게 되고 기존 사용자에게 업데이트를 줄 수 없으며 평점과 리뷰도 옮겨지지 않는다고 Apple 이 설명합니다.

Intel Mac 지원을 끊어도 되나요?

Apple 은 2026-09-09 소식에서 macOS 26 이 Intel Mac 과 Rosetta 를 지원하는 마지막 릴리스이고 macOS 27 은 Apple silicon 전용이라고 밝혔습니다. Apple silicon 만 지원하려면 Xcode 의 빌드 아키텍처를 arm64 전용으로 하고 다시 빌드해 제출하라고 안내합니다. App Store Connect 릴리스 노트(2026-06-18)는 최소 시스템 버전이 13 이상인 유니버설 macOS 앱이 x86_64 아키텍처를 빼고 Intel Mac 지원을 중단한 채 Mac App Store 에 올릴 수 있다고 알립니다. Flutter 3.47.6 기본 템플릿의 최소 macOS 는 12.0 이므로 arm64 전용으로 줄이려면 13 이상으로 올려야 할 수 있습니다. Flutter 도 Intel(x64) 지원을 단계적으로 줄이는 중이라고 지원 플랫폼 표에서 알립니다. Flutter 3.47.6 의 flutter build macos 는 기본으로 x86_64 와 arm64 를 함께 담은 universal 앱을 만듭니다. Apple silicon 전용으로 만들려면 flutter config --enable-macos-arm64-only 를 켠 뒤 다시 빌드하세요(Flutter 도구의 안내이며 기본값은 앞으로 바뀔 수 있습니다). 업로드 요건으로 못 박은 문장은 확인하지 못했으니, 지원 대상 Mac 은 직접 정하세요.

다음 단계

Mac 앱까지 준비됐다면 제출 직전에 제출 전 체크리스트의 Mac App Store 구역을 훑으세요. iPhone · iPad 앱은 App Store (iOS · iPadOS) 편에서, 다른 스토어는 스토어별 안내에서 고릅니다. 출시한 뒤의 업데이트와 거절 대응은 출시 후 운영에서 다룹니다.

출처