בנייה וחתימה של אפליקציית שולחן עבודה עבור macOS
מצב: האפליקציה בנויה, אך בגרסאות macOS מודרניות (14+) Gatekeeper חוסם אותה מלהפעיל. משתמשים מדווחים: "לא ניתן לפתוח כי Apple לא יכולה לבדוק אותה עבור תוכנה זדונית." הסיבה השורשית היא היעדר חתימת קוד ואישור נוטריון. בלעדיהם, Gatekeeper חוסם את ההפעלה, ועקיפתו דרך "הגדרות מערכת" דורשת פעולות לא סטנדרטיות שרוב המשתמשים לא יבצעו.
ניתן לתקן זאת תוך 3–4 ימים אם השרשרת מוגדרת כראוי: תעודת Developer ID → הרשאות → חתימת קוד → אישור נוטריון → stapling. אנו עושים זאת turnkey עבור Electron, Qt, SwiftUI ופריימוורקים אחרים. עם ניסיון של למעלה מ-5 שנים, מסרנו יותר מ-50 מהדורות עבור macOS — אף אחת לא נחסמה. מדריך האישור של Apple
עלות כניסה: נדרש מנוי לתוכנית Apple Developer Program ($99/שנה) כדי לקבל תעודת Developer ID Application. האישור עצמו חינמי למפתחים.
למה חתימת קוד קריטית
חתימת קוד היא חתימה דיגיטלית שמבטיחה את שלמות האפליקציה. macOS בודקת אותה בכל הפעלה. בלעדיה, Gatekeeper חוסם את האפליקציה, ומאלץ את המשתמש לאשר אותה ידנית דרך "הגדרות מערכת" או Terminal. עבור סביבות ארגוניות זה בלתי מקובל: מדיניות MDM אוסרת על הפעלת אפליקציות לא חתומות. אישור נוטריון מוסיף את הבדיקה של Apple לתוכנה זדונית. שניהם חובה להפצה מחוץ ל-Mac App Store.
איך אנו חותמים ומאשרים אפליקציות macOS
התהליך כולל 2 שלבים חובה: חתימת קוד ואישור נוטריון. ראשית, קבל תעודת Developer ID Application (דורש חשבון Apple Developer). לאחר מכן הגדר את הבנייה עם ההרשאות הנכונות. להלן תצורה מינימלית עבור Electron.
// electron-builder.yml
mac:
target:
- target: dmg
- target: zip
icon: build/icon.icns
category: public.app-category.productivity
hardenedRuntime: true
gatekeeperAssess: false
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist
identity: "Developer ID Application: Company Name (TEAM_ID)" <!-- build/entitlements.mac.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key><true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
<key>com.apple.security.network.client</key><true/>
</dict>
</plist> אילו הרשאות נדרשות עבור אפליקציות Electron?
Electron דורש 4 מפתחות: // electron-builder.yml mac: target: - target: dmg - target: zip icon: build/icon.icns category: public.app-category.productivity hardenedRuntime: true gatekeeperAssess: false entitlements: build/entitlements.mac.plist entitlementsInherit: build/entitlements.mac.plist identity: "Developer ID Application: Company Name (TEAM_ID)" (עבור V8), <!-- build/entitlements.mac.plist --> <?xml version="1.0" encoding="UTF-8"?> <plist version="1.0"> <dict> <key>com.apple.security.cs.allow-jit</key><true/> <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/> <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/> <key>com.apple.security.network.client</key><true/> </dict> </plist> (עבור קומפילציית JIT), allow-jit (עבור Node.js), ו-allow-unsigned-executable-memory (עבור בקשות HTTP). בלעדיהם האפליקציה תקרוס בעת ההפעלה או תיכשל בביצוע בקשות רשת. השווה זאת להרשאות עבור אפליקציות SwiftUI מקוריות: שם בדרך כלל נדרשים רק allow-dyld-environment-variables ו-network.client.
| הרשאה | Electron | SwiftUI | Qt |
|---|---|---|---|
| com.apple.security.cs.allow-jit | כן | לא | כן |
| com.apple.security.cs.allow-unsigned-executable-memory | כן | לא | כן |
| com.apple.security.cs.allow-dyld-environment-variables | כן | לא | כן |
| com.apple.security.network.client | כן | כן | כן |
| com.apple.security.app-sandbox | אופציונלי | כן | אופציונלי |
אישור נוטריון ו-Stapling
לאחר חתימת הקוד אנו מגישים את ה-.dmg לאישור נוטריון דרך com.apple.security.app-sandbox. Apple סורקת את הקבצים הבינאריים עבור וירוסים ותוכנה זדונית. התוצאה היא אישור נוטריון, שמצורף לקובץ באמצעות הפקודה com.apple.security.files.user-selected.read-write.
# Через notarytool (Xcode 13+)
xcrun notarytool submit AppName.dmg \
--apple-id "[email protected]" \
--password "@keychain:AC_PASSWORD" \
--team-id "TEAM_ID" \
--wait
# Stapling (встраивание нотаризационного тикета в файл)
xcrun stapler staple AppName.dmg
Notarytool עובד פי 3 מהר יותר מה-altool הישן ויש לו תמיכה טובה יותר מכיוון שהוא מפותח באופן פעיל על ידי Apple.
תצורת חתימת קוד שלב אחר שלב ב-CI/CD
- קבל תעודת Developer ID Application מפורטל Apple Developer (סוג Developer ID Application, לא Development).
- ייצא את התעודה כקובץ .p12 ואחסן אותה בסודות CI (לדוגמה, GitHub Secrets).
- הגדר את
notarytoolאו מקביל עם ההרשאות הנדרשות (ראה לעיל). - הוסף שלב לייבוא התעודה לתוך צינור ה-CI.
- הגדר שלב אישור נוטריון עם
staplerו-stapling. - בדוק את הבנייה הן מקומית והן ב-CI.
GitHub Actions עבור macOS
---
- uses: actions/checkout@v3
- name: Import Certificate
run: |
echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12
security import certificate.p12 -P "$MACOS_CERTIFICATE_PWD" \
-A -t cert -f pkcs12 -k ~/Library/Keychains/login.keychain
- name: Build and Sign
run: npm run build:mac
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
CSC_LINK: ${{ secrets.MACOS_CERTIFICATE }}
CSC_KEY_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
---
בינארי אוניברסלי (Intel + Apple Silicon)
בינארי אוניברסלי הוא בנייה המכילה את שתי הארכיטקטורות (x86_64 ו-arm64). הוא רץ באופן טבעי על M1/M2/M3 ללא Rosetta 2. זה חובה עבור App Store וסביבות ארגוניות רבות. חיסכון בביצועים: ללא בינארי אוניברסלי אתה מאבד עד 30% על Apple Silicon.
# electron-builder автоматически создаёт universal binary npx electron-builder --mac --universal מה כלול בתצורת ה-turnkey שלנו
| שלב | משך | תוצאה |
|---|---|---|
| ניתוח פרויקט | יום אחד | רשימת הרשאות נדרשות, תעודות, תשתית CI |
| הגדרת בנייה וחתימה | 1–2 ימים | צינור CI עובד עם חתימת קוד |
| אישור נוטריון ובדיקות | יום אחד | .dmg מאושר, עם stapling |
| תיעוד והדרכה | 0.5 יום | README, תיאור תהליך, הוראות צוות |
בנוסף: הגדרת עדכון אוטומטי (Sparkle, Electron auto-updater), חתימה במותג לבן, תמיכה ב-Apple Developer Enterprise Program.
מלכודות טיפוסיות
- שימוש בתעודת Apple Development במקום Developer ID — עובד רק לניפוי באגים.
- חוסר ב-
# Через notarytool (Xcode 13+) xcrun notarytool submit AppName.dmg \ --apple-id "[email protected]" \ --password "@keychain:AC_PASSWORD" \ --team-id "TEAM_ID" \ --wait # Stapling (встраивание нотаризационного тикета в файл) xcrun stapler staple AppName.dmg— אישור הנוטריון ייכשל. - הרשאות שגויות עבור Electron — קריסה בעת ההפעלה.
- דילוג על stapling — משתמשים רואים אזהרה אם לא מקוונים.
- שכחת הבינארי האוניברסלי — אובדן ביצועים על Apple Silicon.
- תעודת Developer ID Application לא תקפה אם בחרת בסוג הלא נכון (חייב להיות Developer ID, לא Development).
- אישור הנוטריון נכשל אם
electron-builderלא מופעל. - האפליקציה קורסת בעת ההפעלה — בדוק הרשאות: עבור Electron,
notarytoolו-- uses: actions/checkout@v3 - name: Import Certificate run: | echo "$MACOS_CERTIFICATE" | base64 --decode > certificate.p12 security import certificate.p12 -P "$MACOS_CERTIFICATE_PWD" \ -A -t cert -f pkcs12 -k ~/Library/Keychains/login.keychain - name: Build and Sign run: npm run build:mac env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} CSC_LINK: ${{ secrets.MACOS_CERTIFICATE }} CSC_KEY_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}הם חובה. - Stapling נכשל אם הקובץ פגום — הרץ את
# electron-builder автоматически создаёт universal binary npx electron-builder --mac --universalמיד לאחרhardenedRuntime: true.
בהתבסס על הניסיון שלנו, אנו ממליצים לבדוק אישור נוטריון בכל מהדורה. אפילו שדרוג גרסת Electron יכול לשבור הרשאות.
לוחות זמנים ואחריות
הגדרה בסיסית אורכת 3–4 ימי עבודה. אנו מבטיחים שהאפליקציה תעבור אישור נוטריון ותרוץ על macOS 10.14 ומעלה. צור קשר כדי להגדיר חתימה תוך 3–4 ימים ולהימנע מחסימות Gatekeeper. קבל ייעוץ לפרויקט שלך — נעזור לך להימנע מטעויות טיפוסיות ולחסוך זמן.







