Guideline 2.3.1: פיצ'רים מוסתרים ועדכוני OTA באפליקציה
מאת Mehdi Azizi
פורסם ב-, 9 דק׳
לפי Guideline 2.3.1, אפל דוחה כל פיצ'ר מוסתר, רדום או כזה שלא מופיע בהערות לבדיקה. מה מותר לשנות מרחוק ומה מחייב build חדש.
Guideline 2.3.1 אוסרת פיצ'רים מוסתרים, רדומים או לא מתועדים: כל מה שהאפליקציה שלך עושה חייב להיות גלוי למשתמש ולבודק. כל חידוש צריך תיאור מדויק בהערות לבדיקה. עדכון מרחוק יכול לתקן את מה שאפל ראתה, אבל אף פעם לא להוסיף משהו שאפל לא ראתה.
אני מפרסם את אפליקציות ה-iOS שלי עם Expo, וכל אחת מהן כוללת EAS Update כבר מה-build הראשון, כדי לשלוח תיקונים. הכלל שלי: אף עדכון מרחוק בזמן שגרסה נמצאת בבדיקה. המדריך הזה מבוסס על הטקסט של אפל, על הרישיון שלה, על התיעוד של Expo ועל דחיות שפורסמו.
מה אומרת Guideline 2.3.1?
סעיף 2.3.1 פותח את חלק 2.3 "Accurate Metadata" ב-App Review Guidelines, בתוך פרק 2 "Performance". הטקסט נפתח כך: "Don't include any hidden, dormant, or undocumented features in your app; your app's functionality should be clear to end users and App Review." במילים פשוטות: שום דבר מוסתר, רדום או לא מתועד.
ההמשך נוגע לכל הגשה: "All new features, functionality, and product changes must be described with specificity in the Notes for Review section of App Store Connect (generic descriptions will be rejected) and accessible for review." כל חידוש צריך להיות מתואר במדויק בהערות לבדיקה, ונגיש לבודק. כלומר "תיקוני באגים ושיפורים" לא מספיק.
אותה פסקה מכוונת גם לשיווק מטעה: להבטיח תוכן או שירות שלא קיימים, או להציג מחיר כוזב, ב-App Store או בכל מקום אחר.
החלק הזה עזר לי ב-Nolera. כשקראתי שוב את דף האפליקציה לפני ההשקה, מצאתי שני משפטים שאי אפשר לאמת: "ממשק בצרפתית בלבד", שכבר לא היה נכון, ו"החבילה הנבחרת ביותר", באפליקציה שעוד לא פורסמה בכלל. גם ההערות לבודק תיארו מצב ישן של המוצר. זה בדיוק מה שהחלק הזה מכוון אליו. סעיף 2.3.10, לעומת זאת, מכוון בעיקר לדף האפליקציה.
מה אומרת הודעת הדחייה של 2.3.1?
הדחייה נקראת "Guideline 2.3.1 - Performance", ולפעמים מגיע אחריה "Hidden Features". שתי הודעות שפרסמו מפתחי React Native:
- מרץ 2024, ב-issue ב-GitHub של CodePush: "The app contains hidden features.", בלי שום פירוט נוסף. המפתח מבקש הבהרה ומקבל תוספת לפי 2.5.2: "Your app, extension, or linked framework appears to contain code designed explicitly with the capability to change the app's behavior or functionality after App Review approval." ה-issue לא מספר אם האפליקציה עברה אחר כך.
- פברואר 2023, ב-issue אחר, אפל מכוונת ל-"CodePush-related remote code downloading/updating support" שבבינארי.
הקריאה שלי: הבודק לא רואה את העדכונים שלך, הוא רואה את הקוד שמסוגל לקבל אותם. שני המקרים האלה נוגעים ל-CodePush. לא מצאתי דחייה פומבית עדכנית שמכוונת ל-EAS Update, וזה לא מוכיח כלום.
עדכונים מרחוק: מה מאפשרים 2.5.2 והרישיון
סעיף 2.5.2, שאני מתייחס אליו גם במדריך על מצבי רקע, אוסר על האפליקציה "download, install, or execute code which introduces or changes features or functionality of the app".
סעיף 3.3.1(B) ב-Apple Developer Program License Agreement אוסר קוד הרצה שהורד, אבל מבהיר: "Interpreted code may be downloaded to an Application". בשלושה תנאים: הקוד לא משנה את המטרה העיקרית של האפליקציה, הוא לא עוקף את החתימה, את ה-sandbox או את מנגנוני האבטחה של המערכת, והוא לא יוצר חנות של אפליקציות אחרות.
ה-JavaScript של אפליקציית Expo הוא קוד מפורש (interpreted): לדעתי EAS Update נכנס למסגרת הזו. ה-תיעוד שלו מזכיר שהעדכונים כפופים לכללי ה-App Store, ושה-"changes to your app's behavior need to be reviewed". לבאג קריטי, Expo מציעה תיקון מרחוק, ואחר כך הגשה חדשה שכוללת אותו.
הקו שלי: לתקן ולכוונן את מה שכבר קיים, כן. לשנות את מה שהאפליקציה היא או את מה שהיא מוכרת, לא.
מה אפשר לשנות מרחוק ומה מחייב build חדש
הטבלה שאני עובד לפיה, מבוססת על הדפים של אפל ו-Expo שמצוטטים כאן. השורה "חינמי שהופך לבתשלום" ושתי האחרונות הן הפרשנות שלי.
| שינוי | דרך | למה |
|---|---|---|
| באג JavaScript | עדכון מרחוק | שימוש ש-Expo מתכננת |
| טקסט, תרגום, עיצוב | עדכון מרחוק | שימוש ש-Expo מתכננת |
| מחיר מנוי | App Store Connect | שום קוד לא משתנה |
| Promotional Text | App Store Connect | בלי הגשה חדשה |
| רכישה מסוג שכבר אושר | בדיקה של הרכישה בלבד | כלל של App Store Connect |
| רכישה ראשונה מסוג מסוים | גרסה חדשה | כלל של App Store Connect |
| פיצ'ר חדש | גרסה חדשה | 2.3.1 ו-2.5.2 |
| חינמי שהופך לבתשלום | גרסה חדשה | צריך לעדכן דף והערות |
| הרשאה, Info.plist | build חדש | קובץ בתוך הבינארי |
| מודול נייטיב, Expo SDK | build חדש | קוד נייטיב שהשתנה |
| מתג שמכבה | קונפיגורציה מרחוק | מקובל אם זמני |
| מתג שחושף | אסור | פיצ'ר שמעולם לא נבדק |
את ה-Promotional Text אפשר לשנות "without requiring an updated submission", לפי הדף של אפל על מידע הגרסה. הרכישה הראשונה מכל סוג נשלחת עם גרסה חדשה, והבאות לבד, לפי דף העזרה על הגשת רכישות. Expo מסווגת קוד נייטיב, הרשאות וגרסת SDK כדברים שדורשים בינארי חדש, כמו במקרה של ITMS-90683. מתג שמכבה פיצ'ר תקול לא מוסיף שום דבר חדש, כל עוד הוא לא מוריד משהו שהמנויים שילמו עליו.
מתגים מרחוק בלי דחייה
מתג מרחוק, או feature flag, לא אסור כשלעצמו: הכול תלוי במה שהוא מסתיר. הכללים שלי:
- כל מה שמתג יכול להציג קיים ודולק בשביל הבודק, ומוזכר בשמו בהערות לבדיקה.
- בדיקת A/B משווה בין שתי גרסאות שהבודק יכול לראות, אף פעם לא בין גרסה שנבדקה לגרסה חדשה.
- שום קוד לא מזהה את הבדיקה כדי להתנהג אחרת. זו ההגדרה עצמה של פיצ'ר מוסתר.
- paywall שמנוהל מרחוק מציג רק מוצרים שאושרו, וכל גרסה שלו עומדת ב-סעיף 3.1.2.
מצב דמו וחשבונות בדיקה
Guideline 2.1 דורשת חשבון דמו אם יש באפליקציה שלך התחברות, עם שרת פעיל. אם חובות חוקיות או אבטחתיות מונעות ממך לספק חשבון כזה, מצב דמו מובנה יכול להחליף אותו, אבל רק "with prior approval by Apple", והוא חייב להציג את כל הפיצ'רים. הדף של אפל על מידע הגרסה מוסיף: החשבון לא פג תוקף, וחשבונות נוספים נכנסים להערות, שמוגבלות ל-4,000 בתים.
הקשר ל-2.3.1: מצב דמו או חשבון בדיקה שפותח מסכים שאחרת לא נראים חייב להיות מתואר. מחווה סודית, קוד או חשבון מיוחד שלא דווחו עליהם, זה פיצ'ר מוסתר. תן שם לכל גישה מיוחדת בהערות, ותכתוב מה היא פותחת.
הכלל שלי: אף עדכון מרחוק בזמן בדיקה
למה EAS Update נמצא אצלי בכל מקום: ב-Solys, השעון המעורר שלי, באג JavaScript השתיק את האפליקציה ברגע שאפקט קולי נכשל פעם אחת. התיקון היה שלוש שורות, אבל כדי לשלוח אותו היה צריך build מלא ובדיקה. מאז, כל האפליקציות שלי כוללות expo-updates מה-build הראשון: זה מודול נייטיב, ובינארי שקומפל בלעדיו לעולם לא יקבל כלום. הקונפיגורציה שלי, ב-app.json:
{
"expo": {
"runtimeVersion": { "policy": "fingerprint" },
"updates": { "fallbackToCacheTimeout": 0, "checkAutomatically": "ON_LOAD" }
}
}
עם fingerprint, עדכון מגיע רק לבינאריים שהקוד הנייטיב שלהם תואם (runtime versions). אבל כשגרסה ממתינה לבדיקה או נמצאת בבדיקה, אני לא מפרסם כלום. משתי סיבות.
- הבודק לא יראה את התיקון. עם
fallbackToCacheTimeoutעל 0, התקנה חדשה עולה על הקוד המובנה ומחילה את העדכון רק בהפעלה הבאה (התיעוד של expo-updates). הבודק מתקין, מפעיל פעם אחת ובודק את הבינארי. Nolera נדחתה כשתיקון כבר נשלח מרחוק: אני מספר על זה במדריך על 2.1. - מה שהבודק בודק צריך להישאר מה שהמשתמשים מקבלים. שינוי התנהגות בזמן הבדיקה יוצר פער בין הגרסה שנבדקה לגרסה שנשלחה.
הערות לבדיקה מדויקות
2.3.1 דוחה תיאורים כלליים. התבנית שהייתי משתמש בה, באנגלית:
What's new in this version:
- [Feature]: [where to find it, how to test it].
Remote configuration:
- "[flag]" controls [feature]. It is ON for review.
Over-the-air updates:
- The app uses expo-updates for bug fixes only.
No update will be published during this review.
Demo account: see Sign-in information. It never expires.
איך עונים על דחייה לפי 2.3.1?
תענה ב-App Store Connect, איפה שעונים להודעה של App Review.
- ההודעה נשארת מעורפלת: תשאל לאיזה פיצ'ר הם מתכוונים, כמו המפתח מה-issue של 2024.
- פיצ'ר אמיתי מתואר לא טוב: תן את הנתיב המדויק וסרטון קצר, ואז תשלים את ההערות.
- מתג חושף משהו חדש: תוריד אותו, או תדליק ותתאר אותו, ואז תעשה build מחדש.
- קוד העדכונים הוא הבעיה: תסביר שהוא משמש לתיקונים, במסגרת סעיף 3.3.1(B). ב-issue של 2023, אפל ביקשה להסיר אותו.
הצ'קליסט של 2.3.1 לפני הגשה
- כל חידוש בגרסה מתואר בהערות, עם הנתיב אליו.
- כל מתג מרחוק דולק לבדיקה ומוזכר בשמו בהערות.
- שום קוד לא משנה התנהגות בשביל הבודק.
- הגישות המיוחדות מתוארות: מצב דמו, חשבון בדיקה, מחווה.
- הדף וה-paywall לא מבטיחים שום דבר שה-build לא עושה.
- שום עדכון מרחוק לא מתפרסם בזמן הבדיקה.
לבדוק את התיק שלך לפני השליחה
ה-Review Kit מרכז את הצ'קליסט שלי לפני השליחה, תבניות הערות לבודק ו-skills של Claude Code שעוברים על הפרויקט שלך. אם אתה רוצה עין אנושית, תקבע איתי שעה: נעבור יחד על ההערות לבדיקה ועל קונפיגורציית העדכונים שלך, בשיחת וידאו. התהליך המלא נמצא בדף אפליקציה שנדחתה על ידי אפל.
מכין את ההשקה הראשונה שלך? תעשה את האבחון החינמי: הוא מסדר את השלבים לפי הסדר ושולח לך את הצ'קליסט שלי נגד דחיות של אפל.
שאלות נפוצות
מה המשמעות של "Guideline 2.3.1 - Performance - Hidden Features"?
אפל חושבת שהאפליקציה שלך מכילה פיצ'ר מוסתר, רדום או כזה שלא מופיע בהערות לבדיקה. ההודעה יכולה גם לכוון לקוד שמסוגל לשנות את האפליקציה אחרי הבדיקה, לפעמים יחד עם דחייה לפי 2.5.2.
האם אפל מאשרת את EAS Update?
הרישיון מתיר קוד מפורש שהורד, כל עוד הוא לא משנה את המטרה העיקרית של האפליקציה. לתקן, כן. להוסיף פיצ'ר שלא נבדק, לא.
אפשר להשתמש ב-feature flags באפליקציית iOS?
כן, אם כל מה שהם יכולים להציג עבר בדיקה. תדליק כל מתג לבדיקה ותתאר אותו בהערות.
צריך לדווח לבודק על מצב דמו?
כן. מצב דמו מובנה דורש אישור מראש מאפל וחייב להציג את כל הפיצ'רים.
אפשר לפרסם עדכון מרחוק בזמן הבדיקה?
שום דבר לא אוסר את זה במפורש. אבל הבודק לא יראה אותו בהפעלה הראשונה, והוא יוצר פער מול הגרסה שנבדקה. אני תמיד נמנע מזה.

