2016-06-12 17:51:35 +00:00
|
|
|
|
# Mac 앱 스토어 애플리케이션 제출 가이드
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2015-11-19 17:25:44 +00:00
|
|
|
|
Electron은 v0.34.0 버전부터 앱 패키지를 Mac App Store(MAS)에 제출할 수 있게
|
2016-06-12 17:51:35 +00:00
|
|
|
|
되었습니다. 이 가이드는 애플리케이션을 앱 스토어에 등록하는 방법과 빌드의 한계에 대한
|
2015-11-19 17:25:44 +00:00
|
|
|
|
설명을 제공합니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
**참고:** Mac App Store에 애플리케이션을 등록하려면
|
2015-11-30 08:24:43 +00:00
|
|
|
|
[Apple Developer Program][developer-program]에 등록되어 있어야 하며 비용이 발생할
|
|
|
|
|
수 있습니다.
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
## 앱 스토어에 애플리케이션을 등록하는 방법
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
다음 몇 가지 간단한 절차에 따라 앱 스토어에 애플리케이션을 등록하는 방법을 알아봅니다.
|
2015-11-19 19:58:51 +00:00
|
|
|
|
한가지, 이 절차는 제출한 앱이 Apple로부터 승인되는 것을 보장하지 않습니다. 따라서
|
2015-11-19 17:25:44 +00:00
|
|
|
|
여전히 Apple의 [Submitting Your App][submitting-your-app] 가이드를 숙지하고 있어야
|
2016-04-11 01:34:56 +00:00
|
|
|
|
하며 앱 스토어 제출 요구 사항을 확실히 인지하고 있어야 합니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2015-11-16 20:09:27 +00:00
|
|
|
|
### 인증서 취득
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
앱 스토어에 애플리케이션을 제출하려면, 먼저 Apple로부터 인증서를 취득해야 합니다. 취득
|
2015-11-19 17:25:44 +00:00
|
|
|
|
방법은 웹에서 찾아볼 수 있는 [가이드][nwjs-guide]를 참고하면 됩니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-05-19 08:22:51 +00:00
|
|
|
|
### Team ID 얻기
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
애플리케이션에 서명하기 전에, 먼저 개발 계정의 Team ID를 알아야 합니다. Team ID를
|
2016-05-19 08:22:51 +00:00
|
|
|
|
알아보려면 [Apple Developer Center](https://developer.apple.com/account/)에
|
|
|
|
|
로그인한 후, 사이드바의 Membership을 클릭합니다. Team ID는 Membership Information
|
|
|
|
|
섹션의 팀 이름 밑에 위치합니다.
|
|
|
|
|
|
2015-11-17 01:50:06 +00:00
|
|
|
|
### 앱에 서명하기
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
준비 작업이 끝난 후, [애플리케이션 배포](application-distribution.md) 문서에 따라
|
|
|
|
|
애플리케이션을 패키징한 후 애플리케이션에 서명합니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
먼저, Team ID를 키로 가지고 있는 애플리케이션의 `Info.plist`에 `ElectronTeamID` 키를
|
2016-05-19 08:22:51 +00:00
|
|
|
|
추가해야 합니다:
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
<plist version="1.0">
|
|
|
|
|
<dict>
|
|
|
|
|
...
|
|
|
|
|
<key>ElectronTeamID</key>
|
|
|
|
|
<string>TEAM_ID</string>
|
|
|
|
|
</dict>
|
|
|
|
|
</plist>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
그리고, 다음 두 자격 파일을 준비해야 합니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
|
|
|
|
`child.plist`:
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
|
|
|
<plist version="1.0">
|
|
|
|
|
<dict>
|
|
|
|
|
<key>com.apple.security.app-sandbox</key>
|
|
|
|
|
<true/>
|
|
|
|
|
<key>com.apple.security.inherit</key>
|
|
|
|
|
<true/>
|
|
|
|
|
</dict>
|
|
|
|
|
</plist>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`parent.plist`:
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
|
|
|
<plist version="1.0">
|
|
|
|
|
<dict>
|
|
|
|
|
<key>com.apple.security.app-sandbox</key>
|
|
|
|
|
<true/>
|
2016-05-19 08:22:51 +00:00
|
|
|
|
<key>com.apple.security.application-groups</key>
|
|
|
|
|
<string>TEAM_ID.your.bundle.id</string>
|
2015-11-16 20:05:11 +00:00
|
|
|
|
</dict>
|
|
|
|
|
</plist>
|
|
|
|
|
```
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
`TEAM_ID` 부분은 Team ID로 치환하고, `your.bundle.id` 부분은 애플리케이션의 Bundle
|
2016-05-19 08:22:51 +00:00
|
|
|
|
ID로 치환해야 합니다.
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
그리고 다음 스크립트를 통해 애플리케이션에 서명합니다:
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
# 애플리케이션의 이름.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
APP="YourApp"
|
2016-06-12 17:51:35 +00:00
|
|
|
|
# 서명할 애플리케이션의 경로.
|
2016-04-30 16:53:21 +00:00
|
|
|
|
APP_PATH="/path/to/YourApp.app"
|
2016-06-02 14:50:50 +00:00
|
|
|
|
# 서명된 패키지의 출력 경로.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
RESULT_PATH="~/Desktop/$APP.pkg"
|
2016-06-02 14:50:50 +00:00
|
|
|
|
# 요청한 인증서의 이름.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
APP_KEY="3rd Party Mac Developer Application: Company Name (APPIDENTITY)"
|
|
|
|
|
INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)"
|
2016-06-02 14:50:50 +00:00
|
|
|
|
# plist 파일의 경로.
|
|
|
|
|
CHILD_PLIST="/path/to/child.plist"
|
|
|
|
|
PARENT_PLIST="/path/to/parent.plist"
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
|
|
|
|
FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
|
|
|
|
|
|
2016-06-02 14:50:50 +00:00
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
|
|
|
|
|
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"
|
2016-01-30 22:05:39 +00:00
|
|
|
|
|
2015-11-16 20:05:11 +00:00
|
|
|
|
productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"
|
|
|
|
|
```
|
|
|
|
|
|
2016-06-18 13:26:26 +00:00
|
|
|
|
만약 macOS의 샌드박스 개념에 대해 처음 접한다면 Apple의 [Enabling App Sandbox][enable-app-sandbox]
|
2015-11-19 17:25:44 +00:00
|
|
|
|
문서를 참고하여 기본적인 개념을 이해해야 합니다. 그리고 자격(plist) 파일에
|
2016-06-12 17:51:35 +00:00
|
|
|
|
애플리케이션에서 요구하는 권한의 키를 추가합니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-09 00:59:14 +00:00
|
|
|
|
|
2016-06-13 03:19:37 +00:00
|
|
|
|
그 외에 별로도 [electron-osx-sign][electron-osx-sign] 모듈을 사용하여 직접 서명할
|
|
|
|
|
수도 있습니다.
|
2016-06-09 00:59:14 +00:00
|
|
|
|
|
2016-06-13 03:19:37 +00:00
|
|
|
|
#### 네이티브 모듈에 서명하기
|
|
|
|
|
|
|
|
|
|
앱 내부에서 사용한 네이티브 모듈도 서명이 필요합니다. `electron-osx-sign`을
|
|
|
|
|
사용한다면, 인수 목록에 빌트인 바이너리 경로가 포함되어 있는지 확인해야 합니다:
|
2016-06-09 00:59:14 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
electron-osx-sign YourApp.app YourApp.app/Contents/Resources/app/node_modules/nativemodule/build/release/nativemodule
|
|
|
|
|
```
|
|
|
|
|
|
2016-06-13 03:19:37 +00:00
|
|
|
|
참고로 네이티브 모듈이 의도하지 않게 중간 파일을 포함하는 경우도 있으며 이 파일은
|
|
|
|
|
포함되어선 안됩니다. (해당 파일에도 서명해야 할 수도 있습니다)
|
|
|
|
|
[electron-packager][electron-packager]를 사용한다면, 빌드 과정에 `--ignore=.+\.o$`
|
|
|
|
|
인수를 추가하여 중간 파일을 무시할 수 있습니다.
|
2016-06-09 00:59:14 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
### 애플리케이션 업로드
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
애플리케이션 서명을 완료한 후 iTunes Connect에 업로드하기 위해 Application Loader를
|
2015-11-19 17:25:44 +00:00
|
|
|
|
사용할 수 있습니다. 참고로 업로드하기 전에 [레코드][create-record]를 만들었는지
|
2016-04-20 09:45:07 +00:00
|
|
|
|
확인해야 합니다.
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
### 애플리케이션을 심사에 제출
|
2016-04-20 09:45:07 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
위 과정을 마치면 [애플리케이션을 심사를 위해 제출][submit-for-review]할 수 있습니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2015-11-16 20:09:27 +00:00
|
|
|
|
## MAS 빌드의 한계
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
모든 애플리케이션 샌드박스에 대한 요구 사항을 충족시키기 위해, 다음 모듈들은 MAS
|
2015-11-19 17:25:44 +00:00
|
|
|
|
빌드에서 비활성화됩니다:
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-01-30 22:05:39 +00:00
|
|
|
|
* `crashReporter`
|
|
|
|
|
* `autoUpdater`
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2015-11-16 20:09:27 +00:00
|
|
|
|
그리고 다음 동작으로 대체됩니다:
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2015-11-16 20:09:27 +00:00
|
|
|
|
* 비디오 캡쳐 기능은 몇몇 장치에서 작동하지 않을 수 있습니다.
|
|
|
|
|
* 특정 접근성 기능이 작동하지 않을 수 있습니다.
|
2016-06-12 17:51:35 +00:00
|
|
|
|
* 애플리케이션이 DNS의 변경을 감지하지 못할 수 있습니다.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
또한 애플리케이션 샌드박스 개념으로 인해 애플리케이션에서 접근할 수 있는 리소스는
|
2016-04-21 03:33:56 +00:00
|
|
|
|
엄격하게 제한되어 있습니다. 자세한 내용은 [앱 샌드박싱][app-sandboxing] 문서를
|
2015-11-19 17:25:44 +00:00
|
|
|
|
참고하세요.
|
2015-11-16 20:05:11 +00:00
|
|
|
|
|
2016-06-19 18:23:36 +00:00
|
|
|
|
### 추가적인 권한
|
|
|
|
|
|
|
|
|
|
Mac 앱 스토어 빌드를 위해 앱에서 사용하는 Electron API에 따라 `parent.plist` 파일에
|
|
|
|
|
추가적인 기능에 대한 권한을 추가해야 할 수도 있습니다.
|
|
|
|
|
|
|
|
|
|
#### dialog.showOpenDialog
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
<key>com.apple.security.files.user-selected.read-only</key>
|
|
|
|
|
<true/>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
자세한 내용은 [User-Selected 파일 접근 활성화 문서][user-selected]를 참고하세요.
|
|
|
|
|
|
|
|
|
|
#### dialog.showSaveDialog
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
<key>com.apple.security.files.user-selected.read-write</key>
|
|
|
|
|
<true/>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
자세한 내용은 [User-Selected 파일 접근 활성화 문서][user-selected]를 참고하세요.
|
|
|
|
|
|
2016-01-30 22:05:39 +00:00
|
|
|
|
## Electron에서 사용하는 암호화 알고리즘
|
|
|
|
|
|
2016-06-12 17:51:35 +00:00
|
|
|
|
국가와 살고 있는 지역에 따라, 맥 앱스토어는 제출한 애플리케이션에서 사용하는 암호화
|
2016-01-30 22:05:39 +00:00
|
|
|
|
알고리즘의 문서를 요구할 수 있습니다. 심지어 U.S. Encryption Registration (ERN)의
|
|
|
|
|
승인 사본을 제출하라고 할 수도 있습니다.
|
|
|
|
|
|
|
|
|
|
Electron은 다음과 같은 암호화 알고리즘을 사용합니다:
|
|
|
|
|
|
|
|
|
|
* AES - [NIST SP 800-38A](http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf), [NIST SP 800-38D](http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf), [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt)
|
|
|
|
|
* HMAC - [FIPS 198-1](http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf)
|
|
|
|
|
* ECDSA - ANS X9.62–2005
|
|
|
|
|
* ECDH - ANS X9.63–2001
|
|
|
|
|
* HKDF - [NIST SP 800-56C](http://csrc.nist.gov/publications/nistpubs/800-56C/SP-800-56C.pdf)
|
|
|
|
|
* PBKDF2 - [RFC 2898](https://tools.ietf.org/html/rfc2898)
|
|
|
|
|
* RSA - [RFC 3447](http://www.ietf.org/rfc/rfc3447)
|
|
|
|
|
* SHA - [FIPS 180-4](http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf)
|
|
|
|
|
* Blowfish - https://www.schneier.com/cryptography/blowfish/
|
|
|
|
|
* CAST - [RFC 2144](https://tools.ietf.org/html/rfc2144), [RFC 2612](https://tools.ietf.org/html/rfc2612)
|
|
|
|
|
* DES - [FIPS 46-3](http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf)
|
|
|
|
|
* DH - [RFC 2631](https://tools.ietf.org/html/rfc2631)
|
|
|
|
|
* DSA - [ANSI X9.30](http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.30-1%3A1997)
|
|
|
|
|
* EC - [SEC 1](http://www.secg.org/sec1-v2.pdf)
|
|
|
|
|
* IDEA - "On the Design and Security of Block Ciphers" book by X. Lai
|
|
|
|
|
* MD2 - [RFC 1319](http://tools.ietf.org/html/rfc1319)
|
|
|
|
|
* MD4 - [RFC 6150](https://tools.ietf.org/html/rfc6150)
|
|
|
|
|
* MD5 - [RFC 1321](https://tools.ietf.org/html/rfc1321)
|
|
|
|
|
* MDC2 - [ISO/IEC 10118-2](https://www.openssl.org/docs/manmaster/crypto/mdc2.html)
|
|
|
|
|
* RC2 - [RFC 2268](https://tools.ietf.org/html/rfc2268)
|
|
|
|
|
* RC4 - [RFC 4345](https://tools.ietf.org/html/rfc4345)
|
|
|
|
|
* RC5 - http://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf
|
|
|
|
|
* RIPEMD - [ISO/IEC 10118-3](http://webstore.ansi.org/RecordDetail.aspx?sku=ISO%2FIEC%2010118-3:2004)
|
|
|
|
|
|
|
|
|
|
ERN의 승인을 얻는 방법은, 다음 글을 참고하는 것이 좋습니다:
|
2016-06-12 17:51:35 +00:00
|
|
|
|
[애플리케이션이 암호화를 사용할 때, 합법적으로 Apple의 앱 스토어에 제출하는 방법 (또는 ERN의 승인을 얻는 방법)][ern-tutorial].
|
2016-01-30 22:05:39 +00:00
|
|
|
|
|
2016-06-12 18:28:11 +00:00
|
|
|
|
**역자주:** [Mac 앱 배포 가이드 공식 한국어 문서](https://developer.apple.com/osx/distribution/kr/)
|
2015-11-16 20:17:24 +00:00
|
|
|
|
|
2015-11-30 08:24:43 +00:00
|
|
|
|
[developer-program]: https://developer.apple.com/support/compare-memberships/
|
2015-11-16 20:05:11 +00:00
|
|
|
|
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
|
|
|
|
|
[nwjs-guide]: https://github.com/nwjs/nw.js/wiki/Mac-App-Store-%28MAS%29-Submission-Guideline#first-steps
|
|
|
|
|
[enable-app-sandbox]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html
|
|
|
|
|
[create-record]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/CreatingiTunesConnectRecord.html
|
2016-06-09 00:59:14 +00:00
|
|
|
|
[electron-osx-sign]: https://github.com/electron-userland/electron-osx-sign
|
|
|
|
|
[electron-packager]: https://github.com/electron-userland/electron-packager
|
2015-11-16 20:05:11 +00:00
|
|
|
|
[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
|
|
|
|
|
[app-sandboxing]: https://developer.apple.com/app-sandboxing/
|
2016-01-30 22:05:39 +00:00
|
|
|
|
[ern-tutorial]: https://carouselapps.com/2015/12/15/legally-submit-app-apples-app-store-uses-encryption-obtain-ern/
|
2016-04-20 09:45:07 +00:00
|
|
|
|
[temporary-exception]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/AppSandboxTemporaryExceptionEntitlements.html
|
2016-06-19 18:23:36 +00:00
|
|
|
|
[user-selected]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW6]
|