@kennethsolomon/shipkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +321 -0
- package/bin/shipkit.js +146 -0
- package/commands/sk/brainstorm.md +63 -0
- package/commands/sk/branch.md +35 -0
- package/commands/sk/config.md +96 -0
- package/commands/sk/execute-plan.md +85 -0
- package/commands/sk/features.md +238 -0
- package/commands/sk/finish-feature.md +154 -0
- package/commands/sk/help.md +103 -0
- package/commands/sk/hotfix.md +61 -0
- package/commands/sk/plan.md +30 -0
- package/commands/sk/release.md +72 -0
- package/commands/sk/security-check.md +188 -0
- package/commands/sk/set-profile.md +71 -0
- package/commands/sk/status.md +25 -0
- package/commands/sk/update-task.md +35 -0
- package/commands/sk/write-plan.md +72 -0
- package/package.json +23 -0
- package/skills/sk:accessibility/LICENSE.txt +177 -0
- package/skills/sk:accessibility/SKILL.md +150 -0
- package/skills/sk:api-design/LICENSE.txt +177 -0
- package/skills/sk:api-design/SKILL.md +158 -0
- package/skills/sk:brainstorming/SKILL.md +124 -0
- package/skills/sk:debug/SKILL.md +252 -0
- package/skills/sk:debug/debug_conductor.py +177 -0
- package/skills/sk:debug/lib/__init__.py +1 -0
- package/skills/sk:debug/lib/bug_gatherer.py +55 -0
- package/skills/sk:debug/lib/context_reader.py +139 -0
- package/skills/sk:debug/lib/findings_writer.py +76 -0
- package/skills/sk:debug/lib/lessons_writer.py +165 -0
- package/skills/sk:debug/lib/step_runner.py +326 -0
- package/skills/sk:features/SKILL.md +238 -0
- package/skills/sk:frontend-design/LICENSE.txt +177 -0
- package/skills/sk:frontend-design/SKILL.md +191 -0
- package/skills/sk:laravel-init/SKILL.md +37 -0
- package/skills/sk:laravel-new/SKILL.md +68 -0
- package/skills/sk:lint/SKILL.md +113 -0
- package/skills/sk:perf/LICENSE.txt +177 -0
- package/skills/sk:perf/SKILL.md +188 -0
- package/skills/sk:release/SKILL.md +113 -0
- package/skills/sk:release/references/android-checklist.md +269 -0
- package/skills/sk:release/references/ios-checklist.md +339 -0
- package/skills/sk:release/release.sh +378 -0
- package/skills/sk:review/SKILL.md +346 -0
- package/skills/sk:review/references/security-checklist.md +223 -0
- package/skills/sk:schema-migrate/SKILL.md +125 -0
- package/skills/sk:schema-migrate/orms/drizzle.md +546 -0
- package/skills/sk:schema-migrate/orms/laravel.md +367 -0
- package/skills/sk:schema-migrate/orms/prisma.md +357 -0
- package/skills/sk:schema-migrate/orms/rails.md +351 -0
- package/skills/sk:schema-migrate/orms/sqlalchemy.md +385 -0
- package/skills/sk:schema-migrate/references/detection.md +110 -0
- package/skills/sk:setup-claude/SKILL.md +365 -0
- package/skills/sk:setup-claude/references/detection.md +6 -0
- package/skills/sk:setup-claude/references/templates.md +11 -0
- package/skills/sk:setup-claude/scripts/apply_setup_claude.py +443 -0
- package/skills/sk:setup-claude/scripts/detect_arch_changes.py +437 -0
- package/skills/sk:setup-claude/templates/.claude/docs/arch-changelog-guide.md.template +6 -0
- package/skills/sk:setup-claude/templates/.claude/docs/changelog-guide.md.template +12 -0
- package/skills/sk:setup-claude/templates/CHANGELOG.md.template +21 -0
- package/skills/sk:setup-claude/templates/CLAUDE.md.template +299 -0
- package/skills/sk:setup-claude/templates/arch-changelog-guide.md.template +3 -0
- package/skills/sk:setup-claude/templates/changelog-guide.md.template +3 -0
- package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +74 -0
- package/skills/sk:setup-claude/templates/commands/execute-plan.md.template +57 -0
- package/skills/sk:setup-claude/templates/commands/features.md.template +238 -0
- package/skills/sk:setup-claude/templates/commands/finish-feature.md.template +155 -0
- package/skills/sk:setup-claude/templates/commands/plan.md.template +30 -0
- package/skills/sk:setup-claude/templates/commands/re-setup.md.template +38 -0
- package/skills/sk:setup-claude/templates/commands/release.md.template +74 -0
- package/skills/sk:setup-claude/templates/commands/security-check.md.template +172 -0
- package/skills/sk:setup-claude/templates/commands/status.md.template +17 -0
- package/skills/sk:setup-claude/templates/commands/write-plan.md.template +34 -0
- package/skills/sk:setup-claude/templates/finish-feature.md.template +3 -0
- package/skills/sk:setup-claude/templates/plan.md.template +3 -0
- package/skills/sk:setup-claude/templates/status.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks/findings.md.template +19 -0
- package/skills/sk:setup-claude/templates/tasks/lessons.md.template +26 -0
- package/skills/sk:setup-claude/templates/tasks/progress.md.template +20 -0
- package/skills/sk:setup-claude/templates/tasks/security-findings.md.template +5 -0
- package/skills/sk:setup-claude/templates/tasks/todo.md.template +26 -0
- package/skills/sk:setup-claude/templates/tasks/workflow-status.md.template +31 -0
- package/skills/sk:setup-claude/templates/tasks-findings.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-lessons.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-progress.md.template +3 -0
- package/skills/sk:setup-claude/templates/tasks-todo.md.template +3 -0
- package/skills/sk:setup-claude/tests/test_apply_setup_claude.py +193 -0
- package/skills/sk:setup-optimizer/SKILL.md +184 -0
- package/skills/sk:setup-optimizer/lib/__init__.py +24 -0
- package/skills/sk:setup-optimizer/lib/detect.py +205 -0
- package/skills/sk:setup-optimizer/lib/discover.py +221 -0
- package/skills/sk:setup-optimizer/lib/enrich.py +163 -0
- package/skills/sk:setup-optimizer/lib/merge.py +277 -0
- package/skills/sk:setup-optimizer/lib/sidecar.py +129 -0
- package/skills/sk:setup-optimizer/optimize_claude.py +174 -0
- package/skills/sk:setup-optimizer/templates/CLAUDE.md.template +105 -0
- package/skills/sk:skill-creator/LICENSE.txt +202 -0
- package/skills/sk:skill-creator/SKILL.md +479 -0
- package/skills/sk:skill-creator/agents/analyzer.md +274 -0
- package/skills/sk:skill-creator/agents/comparator.md +202 -0
- package/skills/sk:skill-creator/agents/grader.md +223 -0
- package/skills/sk:skill-creator/assets/eval_review.html +146 -0
- package/skills/sk:skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/sk:skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/sk:skill-creator/references/schemas.md +430 -0
- package/skills/sk:skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/sk:skill-creator/scripts/generate_report.py +326 -0
- package/skills/sk:skill-creator/scripts/improve_description.py +248 -0
- package/skills/sk:skill-creator/scripts/package_skill.py +136 -0
- package/skills/sk:skill-creator/scripts/quick_validate.py +103 -0
- package/skills/sk:skill-creator/scripts/run_eval.py +310 -0
- package/skills/sk:skill-creator/scripts/run_loop.py +332 -0
- package/skills/sk:skill-creator/scripts/utils.py +47 -0
- package/skills/sk:smart-commit/SKILL.md +175 -0
- package/skills/sk:test/SKILL.md +171 -0
- package/skills/sk:write-tests/SKILL.md +195 -0
- package/skills/sk:write-tests/references/patterns.md +209 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# Android / Play Store Readiness Checklist
|
|
2
|
+
|
|
3
|
+
Walk through every section below. For each item, check the relevant file, report status, and fix or guide as needed.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Google Play Developer Account
|
|
8
|
+
|
|
9
|
+
- [ ] Developer account exists at https://play.google.com/console
|
|
10
|
+
- [ ] One-time $25 registration fee paid
|
|
11
|
+
- [ ] Developer profile completed (name, email, website, phone)
|
|
12
|
+
- [ ] If using Google Play App Signing (recommended), enrollment is done
|
|
13
|
+
|
|
14
|
+
**First-time guidance**: Walk the user through creating an account if they don't have one.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. App Identity
|
|
19
|
+
|
|
20
|
+
### Package Name / Application ID
|
|
21
|
+
- Check `app.json` > `expo.android.package` (Expo)
|
|
22
|
+
- Check `android/app/build.gradle` > `applicationId` (RN bare / native)
|
|
23
|
+
- Check `pubspec.yaml` or `android/app/build.gradle` (Flutter)
|
|
24
|
+
- Must be reverse-domain format: `com.company.appname`
|
|
25
|
+
- Must be unique on Play Store — cannot be changed after first publish
|
|
26
|
+
- No uppercase letters, no hyphens, only dots and lowercase alphanumeric
|
|
27
|
+
|
|
28
|
+
### Version Code & Version Name
|
|
29
|
+
- `versionCode` must be an integer, must increment with every upload
|
|
30
|
+
- `versionName` is the user-facing version string (e.g., "1.0.0")
|
|
31
|
+
- For Expo: check `app.json` > `expo.android.versionCode` and `expo.version`
|
|
32
|
+
- For bare RN/native: check `android/app/build.gradle` > `defaultConfig`
|
|
33
|
+
- WARN if versionCode is 1 and this is an update (should be incremented)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. App Signing
|
|
38
|
+
|
|
39
|
+
### Expo (EAS Build)
|
|
40
|
+
- Check if `eas.json` exists with a `production` profile
|
|
41
|
+
- Verify `"credentialsSource": "remote"` (recommended) or local keystore configured
|
|
42
|
+
- EAS manages signing automatically — confirm `eas credentials` has been run
|
|
43
|
+
|
|
44
|
+
### React Native (bare) / Native Android
|
|
45
|
+
- Check for `*.keystore` or `*.jks` file
|
|
46
|
+
- Check `android/app/build.gradle` for `signingConfigs.release`
|
|
47
|
+
- Check `android/gradle.properties` for keystore password references
|
|
48
|
+
- WARN if passwords are hardcoded (should use env vars or `gradle.properties` excluded from git)
|
|
49
|
+
- Verify `.gitignore` includes `*.keystore`, `*.jks`
|
|
50
|
+
|
|
51
|
+
### Flutter
|
|
52
|
+
- Check `android/app/build.gradle` for `signingConfigs`
|
|
53
|
+
- Check for `key.properties` file
|
|
54
|
+
- Verify `key.properties` is in `.gitignore`
|
|
55
|
+
|
|
56
|
+
### Play App Signing (all frameworks)
|
|
57
|
+
- Recommend enrollment in Google Play App Signing
|
|
58
|
+
- If using upload key + signing key model, verify upload key is configured
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 4. AndroidManifest.xml
|
|
63
|
+
|
|
64
|
+
Location varies by framework:
|
|
65
|
+
- Expo: auto-generated, check `app.json` > `expo.android.permissions`
|
|
66
|
+
- RN bare: `android/app/src/main/AndroidManifest.xml`
|
|
67
|
+
- Flutter: `android/app/src/main/AndroidManifest.xml`
|
|
68
|
+
- Native: `app/src/main/AndroidManifest.xml`
|
|
69
|
+
|
|
70
|
+
### Permissions Audit
|
|
71
|
+
- List all declared permissions
|
|
72
|
+
- WARN on dangerous permissions that need justification:
|
|
73
|
+
- `READ_CONTACTS`, `ACCESS_FINE_LOCATION`, `CAMERA`, `RECORD_AUDIO`, `READ_PHONE_STATE`
|
|
74
|
+
- `READ_EXTERNAL_STORAGE`, `WRITE_EXTERNAL_STORAGE` (deprecated in API 33+)
|
|
75
|
+
- `QUERY_ALL_PACKAGES` (needs declaration form)
|
|
76
|
+
- FAIL if permissions are declared but not actually used in code
|
|
77
|
+
- For Expo: check `app.json` > `expo.android.permissions` array
|
|
78
|
+
|
|
79
|
+
### Internet Permission
|
|
80
|
+
- Must have `android.permission.INTERNET` (usually default)
|
|
81
|
+
|
|
82
|
+
### Intent Filters
|
|
83
|
+
- Check for deep link / app link intent filters
|
|
84
|
+
- If app uses deep links, verify `autoVerify="true"` and `assetlinks.json` is hosted
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 5. Target SDK & API Levels
|
|
89
|
+
|
|
90
|
+
### Current Google Play Requirements (2024+)
|
|
91
|
+
- `targetSdkVersion` must be **34** (Android 14) or higher for new apps
|
|
92
|
+
- `minSdkVersion` — recommend **24** (Android 7.0) or higher for broad compatibility
|
|
93
|
+
- `compileSdkVersion` should match or exceed `targetSdkVersion`
|
|
94
|
+
|
|
95
|
+
### Where to check
|
|
96
|
+
- Expo: `app.json` > `expo.android.targetSdkVersion` (or defaults from Expo SDK version)
|
|
97
|
+
- RN bare / native: `android/app/build.gradle` > `defaultConfig`
|
|
98
|
+
- Flutter: `android/app/build.gradle` > `defaultConfig`
|
|
99
|
+
|
|
100
|
+
### FAIL conditions
|
|
101
|
+
- `targetSdkVersion` < 34
|
|
102
|
+
- `compileSdkVersion` < `targetSdkVersion`
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 6. App Bundle (AAB)
|
|
107
|
+
|
|
108
|
+
- Google Play requires **Android App Bundle (.aab)** format (not APK) for new apps
|
|
109
|
+
- Verify build configuration produces AAB:
|
|
110
|
+
- Expo/EAS: default for production builds
|
|
111
|
+
- RN bare: `./gradlew bundleRelease`
|
|
112
|
+
- Flutter: `flutter build appbundle`
|
|
113
|
+
- Native: Gradle `bundleRelease` task
|
|
114
|
+
|
|
115
|
+
### ProGuard / R8
|
|
116
|
+
- Check if code shrinking is enabled for release builds
|
|
117
|
+
- `android/app/build.gradle` > `buildTypes.release.minifyEnabled`
|
|
118
|
+
- If enabled, verify ProGuard rules don't strip needed classes
|
|
119
|
+
- For RN: check `proguard-rules.pro` includes React Native rules
|
|
120
|
+
|
|
121
|
+
### 64-bit Support
|
|
122
|
+
- All native libraries must include 64-bit (`arm64-v8a`) builds
|
|
123
|
+
- Check `android/app/build.gradle` > `ndk.abiFilters`
|
|
124
|
+
- Should include at minimum: `armeabi-v7a`, `arm64-v8a`
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 7. App Icons & Assets
|
|
129
|
+
|
|
130
|
+
### Launcher Icon
|
|
131
|
+
- Must provide adaptive icon (foreground + background layers)
|
|
132
|
+
- Sizes: 512x512 for Play Store listing, various mipmap sizes for device
|
|
133
|
+
- Expo: check `app.json` > `expo.android.adaptiveIcon`
|
|
134
|
+
- `foregroundImage`: must exist and be at least 1024x1024
|
|
135
|
+
- `backgroundColor`: should be set
|
|
136
|
+
- RN bare / native: check `android/app/src/main/res/mipmap-*` directories
|
|
137
|
+
- Flutter: check `android/app/src/main/res/mipmap-*`
|
|
138
|
+
|
|
139
|
+
### FAIL conditions
|
|
140
|
+
- No icon configured
|
|
141
|
+
- Icon is placeholder/default
|
|
142
|
+
- Foreground image smaller than 512x512
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 8. Splash Screen
|
|
147
|
+
|
|
148
|
+
- Expo: check `app.json` > `expo.splash` and `expo.android.splash`
|
|
149
|
+
- RN bare: check for splash screen library configuration
|
|
150
|
+
- Should not show default/placeholder splash
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 9. Privacy & Data Safety
|
|
155
|
+
|
|
156
|
+
### Privacy Policy
|
|
157
|
+
- **REQUIRED** for all apps on Google Play
|
|
158
|
+
- Must be a publicly accessible URL
|
|
159
|
+
- Expo: check `app.json` > `expo.android.privacyPolicyUrl` or metadata
|
|
160
|
+
- Must cover: what data is collected, how it's used, third-party sharing
|
|
161
|
+
|
|
162
|
+
### Data Safety Form
|
|
163
|
+
- Must be completed in Play Console before publishing
|
|
164
|
+
- Covers: data collection, sharing, security practices, data deletion
|
|
165
|
+
- Guide user through the form based on what the app actually does:
|
|
166
|
+
- Does the app use analytics? (Firebase, Amplitude, etc.)
|
|
167
|
+
- Does the app collect personal info? (email, name, etc.)
|
|
168
|
+
- Does the app use location?
|
|
169
|
+
- Does the app use advertising IDs?
|
|
170
|
+
- Does the app allow user-generated content?
|
|
171
|
+
|
|
172
|
+
### MANUAL CHECK: Provide a checklist of questions to determine data safety answers
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 10. Content Rating
|
|
177
|
+
|
|
178
|
+
- Must complete content rating questionnaire in Play Console (IARC)
|
|
179
|
+
- App will be rated based on content (violence, language, etc.)
|
|
180
|
+
- MANUAL CHECK: Remind user to complete this in Play Console
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 11. Store Listing
|
|
185
|
+
|
|
186
|
+
All required for Play Store:
|
|
187
|
+
|
|
188
|
+
- [ ] **App name** (max 30 characters)
|
|
189
|
+
- [ ] **Short description** (max 80 characters)
|
|
190
|
+
- [ ] **Full description** (max 4000 characters)
|
|
191
|
+
- [ ] **App icon** (512x512 PNG, 32-bit, no alpha)
|
|
192
|
+
- [ ] **Feature graphic** (1024x500 PNG or JPEG)
|
|
193
|
+
- [ ] **Screenshots** — minimum 2, recommended 8
|
|
194
|
+
- Phone: 16:9 or 9:16, min 320px, max 3840px per side
|
|
195
|
+
- 7-inch tablet: optional but recommended
|
|
196
|
+
- 10-inch tablet: optional but recommended
|
|
197
|
+
- [ ] **App category** selected
|
|
198
|
+
- [ ] **Contact email** provided
|
|
199
|
+
- [ ] **Privacy policy URL** provided
|
|
200
|
+
|
|
201
|
+
### MANUAL CHECK: Guide user on preparing these assets
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 12. Testing Track
|
|
206
|
+
|
|
207
|
+
Recommend using testing tracks before production:
|
|
208
|
+
|
|
209
|
+
1. **Internal testing** — up to 100 testers, instant publish
|
|
210
|
+
2. **Closed testing** — invite-only, good for beta
|
|
211
|
+
3. **Open testing** — anyone can join
|
|
212
|
+
4. **Production** — public release
|
|
213
|
+
|
|
214
|
+
For first-time apps, suggest starting with Internal Testing.
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## 13. Build & Submit Commands
|
|
219
|
+
|
|
220
|
+
### Expo (EAS)
|
|
221
|
+
```bash
|
|
222
|
+
# First time setup
|
|
223
|
+
npx eas-cli login
|
|
224
|
+
npx eas-cli build:configure
|
|
225
|
+
|
|
226
|
+
# Build for Android
|
|
227
|
+
npx eas-cli build --platform android --profile production
|
|
228
|
+
|
|
229
|
+
# Submit to Play Store
|
|
230
|
+
npx eas-cli submit --platform android --profile production
|
|
231
|
+
```
|
|
232
|
+
Note: EAS Submit requires a Google Play Service Account key (`sa_key.json`). Guide user through creating one in Google Cloud Console if not present.
|
|
233
|
+
|
|
234
|
+
### React Native (bare)
|
|
235
|
+
```bash
|
|
236
|
+
cd android && ./gradlew bundleRelease
|
|
237
|
+
# Output: android/app/build/outputs/bundle/release/app-release.aab
|
|
238
|
+
# Upload manually via Play Console or use `fastlane supply`
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Flutter
|
|
242
|
+
```bash
|
|
243
|
+
flutter build appbundle --release
|
|
244
|
+
# Output: build/app/outputs/bundle/release/app-release.aab
|
|
245
|
+
# Upload manually via Play Console or use `fastlane supply`
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Native Android
|
|
249
|
+
```bash
|
|
250
|
+
./gradlew bundleRelease
|
|
251
|
+
# Upload via Play Console
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## 14. Common Rejection Reasons
|
|
257
|
+
|
|
258
|
+
Check for these before submitting:
|
|
259
|
+
|
|
260
|
+
1. **Crashes on launch** — test on a real device or emulator before submitting
|
|
261
|
+
2. **Missing privacy policy** — required for all apps
|
|
262
|
+
3. **Misleading metadata** — app description must match actual functionality
|
|
263
|
+
4. **Broken functionality** — all advertised features must work
|
|
264
|
+
5. **Intellectual property** — no trademarked names/logos without permission
|
|
265
|
+
6. **Background location** — requires extra justification form if used
|
|
266
|
+
7. **All Files Access** — `MANAGE_EXTERNAL_STORAGE` needs approval form
|
|
267
|
+
8. **Accessibility services** — if using AccessibilityService API, needs declaration
|
|
268
|
+
9. **SMS/Call Log permissions** — restricted, needs declaration form
|
|
269
|
+
10. **Photos/Videos permission** — use granular media permissions on API 33+
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# iOS / App Store Readiness Checklist
|
|
2
|
+
|
|
3
|
+
Walk through every section below. For each item, check the relevant file, report status, and fix or guide as needed.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Apple Developer Account
|
|
8
|
+
|
|
9
|
+
- [ ] Enrolled in Apple Developer Program at https://developer.apple.com
|
|
10
|
+
- [ ] $99/year membership is active
|
|
11
|
+
- [ ] Team / individual account type chosen
|
|
12
|
+
- [ ] Agreements in App Store Connect are all accepted (check for updated agreements — this blocks submissions)
|
|
13
|
+
|
|
14
|
+
**First-time guidance**: Walk the user through enrollment. Note: can take 24-48 hours for approval.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. App Identity
|
|
19
|
+
|
|
20
|
+
### Bundle Identifier
|
|
21
|
+
- Must be reverse-domain format: `com.company.appname`
|
|
22
|
+
- Must be unique on App Store — cannot be changed after first publish
|
|
23
|
+
- Expo: check `app.json` > `expo.ios.bundleIdentifier`
|
|
24
|
+
- RN bare: check `ios/<AppName>.xcodeproj/project.pbxproj` > `PRODUCT_BUNDLE_IDENTIFIER`
|
|
25
|
+
- Flutter: check `ios/Runner.xcodeproj/project.pbxproj` or `ios/Runner/Info.plist`
|
|
26
|
+
- Native: check Xcode project settings > General > Bundle Identifier
|
|
27
|
+
|
|
28
|
+
### Version & Build Number
|
|
29
|
+
- `CFBundleShortVersionString` — user-facing version (e.g., "1.0.0")
|
|
30
|
+
- `CFBundleVersion` — build number, must increment with every upload
|
|
31
|
+
- Expo: check `app.json` > `expo.version` and `expo.ios.buildNumber`
|
|
32
|
+
- RN bare / native: check `Info.plist` or Xcode project settings
|
|
33
|
+
- Flutter: check `pubspec.yaml` > `version` (format: "1.0.0+1" where +1 is build number)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. Code Signing
|
|
38
|
+
|
|
39
|
+
### Expo (EAS Build)
|
|
40
|
+
- Check if `eas.json` exists with a `production` profile
|
|
41
|
+
- Verify `"credentialsSource": "remote"` (recommended — EAS manages certs automatically)
|
|
42
|
+
- Or check for local provisioning profile and distribution certificate
|
|
43
|
+
- Confirm `eas credentials` has been configured
|
|
44
|
+
|
|
45
|
+
### React Native (bare) / Native iOS
|
|
46
|
+
- Check for valid Apple Distribution Certificate
|
|
47
|
+
- Check for App Store provisioning profile (not Ad Hoc or Development)
|
|
48
|
+
- Verify Xcode project settings:
|
|
49
|
+
- `CODE_SIGN_IDENTITY` = "Apple Distribution" (or "iPhone Distribution")
|
|
50
|
+
- `PROVISIONING_PROFILE_SPECIFIER` is set
|
|
51
|
+
- `CODE_SIGN_STYLE` = "Manual" (recommended for CI) or "Automatic"
|
|
52
|
+
- If using Automatic Signing, verify Apple ID is configured in Xcode
|
|
53
|
+
|
|
54
|
+
### Flutter
|
|
55
|
+
- Same as native iOS — check `ios/Runner.xcodeproj` signing settings
|
|
56
|
+
- Verify `ios/ExportOptions.plist` if building from CLI
|
|
57
|
+
|
|
58
|
+
### WARN conditions
|
|
59
|
+
- Development provisioning profile used instead of Distribution
|
|
60
|
+
- Ad Hoc profile used instead of App Store profile
|
|
61
|
+
- Certificate expiring within 30 days
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 4. Info.plist
|
|
66
|
+
|
|
67
|
+
Location varies by framework:
|
|
68
|
+
- Expo: auto-generated from `app.json`, check `expo.ios.infoPlist` for overrides
|
|
69
|
+
- RN bare: `ios/<AppName>/Info.plist`
|
|
70
|
+
- Flutter: `ios/Runner/Info.plist`
|
|
71
|
+
- Native: `<Target>/Info.plist`
|
|
72
|
+
|
|
73
|
+
### Required Permission Descriptions (Usage Descriptions)
|
|
74
|
+
Apple REJECTS apps that request permissions without explaining why. Check for these keys and verify descriptions are user-friendly and specific:
|
|
75
|
+
|
|
76
|
+
| Permission | Info.plist Key | Example Description |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Camera | `NSCameraUsageDescription` | "Take profile photos" |
|
|
79
|
+
| Photo Library | `NSPhotoLibraryUsageDescription` | "Select images to upload" |
|
|
80
|
+
| Location (in use) | `NSLocationWhenInUseUsageDescription` | "Show nearby restaurants" |
|
|
81
|
+
| Location (always) | `NSLocationAlwaysUsageDescription` | "Track your run in background" |
|
|
82
|
+
| Microphone | `NSMicrophoneUsageDescription` | "Record voice messages" |
|
|
83
|
+
| Contacts | `NSContactsUsageDescription` | "Find friends on the app" |
|
|
84
|
+
| Calendar | `NSCalendarsUsageDescription` | "Add events to your calendar" |
|
|
85
|
+
| Face ID | `NSFaceIDUsageDescription` | "Unlock the app with Face ID" |
|
|
86
|
+
| Bluetooth | `NSBluetoothAlwaysUsageDescription` | "Connect to nearby devices" |
|
|
87
|
+
| Tracking | `NSUserTrackingUsageDescription` | "Deliver personalized ads" |
|
|
88
|
+
|
|
89
|
+
**FAIL conditions:**
|
|
90
|
+
- Permission key exists but description is empty or generic ("This app needs access")
|
|
91
|
+
- Permission is requested in code but key is missing from Info.plist
|
|
92
|
+
- Permission key exists but the app doesn't actually use that permission (remove it)
|
|
93
|
+
|
|
94
|
+
### App Transport Security (ATS)
|
|
95
|
+
- Check for `NSAppTransportSecurity` in Info.plist
|
|
96
|
+
- `NSAllowsArbitraryLoads = YES` will trigger review scrutiny — needs justification
|
|
97
|
+
- WARN if arbitrary loads are enabled; recommend using exceptions for specific domains instead
|
|
98
|
+
- For Expo: check `app.json` > `expo.ios.infoPlist.NSAppTransportSecurity`
|
|
99
|
+
|
|
100
|
+
### Other Required Keys
|
|
101
|
+
- `UIRequiredDeviceCapabilities` — verify only capabilities the app truly needs
|
|
102
|
+
- `UISupportedInterfaceOrientations` — verify matches app design
|
|
103
|
+
- `UILaunchStoryboardName` — must be present (usually "SplashScreen" or "LaunchScreen")
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 5. Privacy Manifest (Required since Spring 2024)
|
|
108
|
+
|
|
109
|
+
Apple now requires a **Privacy Manifest** (`PrivacyInfo.xcprivacy`) for:
|
|
110
|
+
- Apps that use certain APIs (Required Reason APIs)
|
|
111
|
+
- Apps that include SDKs on Apple's list of SDKs requiring privacy manifests
|
|
112
|
+
|
|
113
|
+
### Required Reason APIs to check for:
|
|
114
|
+
- `NSUserDefaults` — reason: "CA92.1" (app functionality)
|
|
115
|
+
- `fileTimestamp` APIs — file modification dates
|
|
116
|
+
- `systemUptime` / `mach_absolute_time` — system boot time
|
|
117
|
+
- `diskSpace` APIs — available disk space
|
|
118
|
+
- `activeKeyboards` — user's keyboard list
|
|
119
|
+
|
|
120
|
+
### Where to check
|
|
121
|
+
- Expo: SDK 50+ handles this automatically for built-in modules. Check if third-party libraries need entries.
|
|
122
|
+
- RN bare / native: check `ios/PrivacyInfo.xcprivacy` exists
|
|
123
|
+
- Flutter: check `ios/Runner/PrivacyInfo.xcprivacy`
|
|
124
|
+
|
|
125
|
+
### FAIL conditions
|
|
126
|
+
- No `PrivacyInfo.xcprivacy` and app uses Required Reason APIs
|
|
127
|
+
- Privacy manifest doesn't declare all Required Reason APIs used
|
|
128
|
+
|
|
129
|
+
### How to fix
|
|
130
|
+
Create or update `PrivacyInfo.xcprivacy` with the correct `NSPrivacyAccessedAPITypes` entries. Provide the exact XML for the user's detected API usage.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 6. App Icons
|
|
135
|
+
|
|
136
|
+
### Required
|
|
137
|
+
- 1024x1024 App Store icon (no alpha channel, no rounded corners — Apple applies them)
|
|
138
|
+
- Expo: check `app.json` > `expo.icon` and `expo.ios.icon`
|
|
139
|
+
- RN bare / native: check `ios/<AppName>/Images.xcassets/AppIcon.appiconset`
|
|
140
|
+
- Flutter: check `ios/Runner/Assets.xcassets/AppIcon.appiconset`
|
|
141
|
+
|
|
142
|
+
### FAIL conditions
|
|
143
|
+
- No icon configured
|
|
144
|
+
- Icon includes alpha/transparency (App Store rejects this)
|
|
145
|
+
- Icon is a placeholder
|
|
146
|
+
- Icon contains text that's too small to read
|
|
147
|
+
- `Contents.json` in the asset catalog is incomplete
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 7. Launch Screen / Splash Screen
|
|
152
|
+
|
|
153
|
+
- Must have a launch screen (Apple rejects apps without one)
|
|
154
|
+
- Expo: check `app.json` > `expo.splash` and `expo.ios.splash`
|
|
155
|
+
- RN bare: check `ios/<AppName>/LaunchScreen.storyboard` or `LaunchScreen.xib`
|
|
156
|
+
- Flutter: check `ios/Runner/Base.lproj/LaunchScreen.storyboard`
|
|
157
|
+
- Must not be a plain blank white/black screen (Apple may reject)
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 8. Deployment Target
|
|
162
|
+
|
|
163
|
+
### Minimum iOS Version
|
|
164
|
+
- Check `IPHONEOS_DEPLOYMENT_TARGET` in Xcode project
|
|
165
|
+
- Expo: determined by Expo SDK version (SDK 51+ requires iOS 15.1+)
|
|
166
|
+
- Recommend: iOS 16.0+ for new apps (covers ~95% of active devices)
|
|
167
|
+
- WARN if targeting below iOS 15
|
|
168
|
+
|
|
169
|
+
### Supported Architectures
|
|
170
|
+
- Must support `arm64` (all modern iPhones)
|
|
171
|
+
- Should NOT include `i386` or `x86_64` only (simulator-only archs)
|
|
172
|
+
- Check `ARCHS` and `VALID_ARCHS` in build settings
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 9. Privacy & Data Collection
|
|
177
|
+
|
|
178
|
+
### Privacy Policy
|
|
179
|
+
- **REQUIRED** for all apps on the App Store
|
|
180
|
+
- Must be a publicly accessible URL
|
|
181
|
+
- Expo: often set in `app.json` or in App Store Connect
|
|
182
|
+
- Must cover: what data is collected, how it's used, third-party sharing, data retention, deletion
|
|
183
|
+
|
|
184
|
+
### App Privacy Details (Nutrition Labels)
|
|
185
|
+
- Must be completed in App Store Connect
|
|
186
|
+
- Covers categories: Contact Info, Health & Fitness, Financial Info, Location, etc.
|
|
187
|
+
- For each data type: collected? linked to identity? used for tracking?
|
|
188
|
+
- Guide user through based on actual app behavior:
|
|
189
|
+
- Analytics SDKs (Firebase, Amplitude, Mixpanel)
|
|
190
|
+
- Authentication data (email, name, phone)
|
|
191
|
+
- Location services
|
|
192
|
+
- Device identifiers
|
|
193
|
+
- Crash reporting (Sentry, Bugsnag)
|
|
194
|
+
|
|
195
|
+
### App Tracking Transparency (ATT)
|
|
196
|
+
- If the app tracks users across apps/websites, must implement ATT framework
|
|
197
|
+
- Must show the ATT prompt before tracking
|
|
198
|
+
- Check for `NSUserTrackingUsageDescription` in Info.plist
|
|
199
|
+
- If app doesn't track users, verify no tracking SDKs are included
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 10. App Store Connect Setup
|
|
204
|
+
|
|
205
|
+
### Create App Record
|
|
206
|
+
- Log in to https://appstoreconnect.apple.com
|
|
207
|
+
- Create new app with matching Bundle ID
|
|
208
|
+
- Select primary language and category
|
|
209
|
+
|
|
210
|
+
### Required Store Listing Assets
|
|
211
|
+
- [ ] **App name** (max 30 characters)
|
|
212
|
+
- [ ] **Subtitle** (max 30 characters, optional but recommended)
|
|
213
|
+
- [ ] **Description** (max 4000 characters)
|
|
214
|
+
- [ ] **Keywords** (max 100 characters, comma-separated)
|
|
215
|
+
- [ ] **Support URL**
|
|
216
|
+
- [ ] **Marketing URL** (optional)
|
|
217
|
+
- [ ] **Privacy Policy URL** (required)
|
|
218
|
+
- [ ] **App icon** (1024x1024, uploaded during build or manually)
|
|
219
|
+
|
|
220
|
+
### Screenshots (REQUIRED)
|
|
221
|
+
Must provide for at least these device sizes:
|
|
222
|
+
- **6.7" iPhone** (1290x2796 or 2796x1290) — iPhone 15 Pro Max
|
|
223
|
+
- **6.5" iPhone** (1284x2778 or 2778x1284) — iPhone 14 Plus (can reuse 6.7")
|
|
224
|
+
- **5.5" iPhone** (1242x2208 or 2208x1242) — iPhone 8 Plus
|
|
225
|
+
- **iPad Pro 12.9" 6th gen** (2048x2732) — if app supports iPad
|
|
226
|
+
- **iPad Pro 12.9" 2nd gen** (2048x2732) — if app supports iPad
|
|
227
|
+
|
|
228
|
+
Minimum 1 screenshot per size, maximum 10. Recommended: 4-8 screenshots.
|
|
229
|
+
|
|
230
|
+
### MANUAL CHECK: Guide user on taking/creating screenshots
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 11. App Review Guidelines — Common Rejections
|
|
235
|
+
|
|
236
|
+
Check the app against these common rejection reasons:
|
|
237
|
+
|
|
238
|
+
### 1. Crashes & Bugs
|
|
239
|
+
- App must not crash on launch
|
|
240
|
+
- All advertised features must work
|
|
241
|
+
- Test on a real device before submitting
|
|
242
|
+
|
|
243
|
+
### 2. Minimum Functionality
|
|
244
|
+
- Apple rejects "simple websites wrapped in an app" (WebView-only apps)
|
|
245
|
+
- App must provide value beyond what a website offers
|
|
246
|
+
- If the app is primarily a WebView, it needs substantial native features
|
|
247
|
+
|
|
248
|
+
### 3. In-App Purchase Requirements
|
|
249
|
+
- **Digital goods/services MUST use Apple's In-App Purchase** (Apple takes 15-30%)
|
|
250
|
+
- Physical goods/services CAN use external payment (Stripe, etc.)
|
|
251
|
+
- Reader apps (Netflix, Spotify) can link to external sign-up since 2022
|
|
252
|
+
- FAIL if the app sells digital content without IAP
|
|
253
|
+
|
|
254
|
+
### 4. Login Requirements
|
|
255
|
+
- If app requires login, must support "Sign in with Apple" (if any third-party social login is offered)
|
|
256
|
+
- Guest access or demo mode recommended for review
|
|
257
|
+
- Provide test credentials in App Store Connect review notes
|
|
258
|
+
|
|
259
|
+
### 5. Privacy
|
|
260
|
+
- Must have privacy policy
|
|
261
|
+
- Must declare all data collection accurately
|
|
262
|
+
- Must not access unnecessary device capabilities
|
|
263
|
+
|
|
264
|
+
### 6. Metadata
|
|
265
|
+
- Screenshots must reflect actual app experience
|
|
266
|
+
- Description must match functionality
|
|
267
|
+
- App name must not include pricing info or "free"
|
|
268
|
+
|
|
269
|
+
### 7. Age Rating
|
|
270
|
+
- Must be accurate — Apple verifies this
|
|
271
|
+
- If app has user-generated content, must include: reporting, blocking, content moderation
|
|
272
|
+
|
|
273
|
+
### 8. Background Modes
|
|
274
|
+
- Only declare background modes (`UIBackgroundModes`) that the app actually uses
|
|
275
|
+
- FAIL if unused background modes are declared (common reason for rejection)
|
|
276
|
+
- Check Info.plist for: `audio`, `location`, `voip`, `fetch`, `remote-notification`, `processing`
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 12. Build & Submit Commands
|
|
281
|
+
|
|
282
|
+
### Expo (EAS)
|
|
283
|
+
```bash
|
|
284
|
+
# First time setup
|
|
285
|
+
npx eas-cli login
|
|
286
|
+
npx eas-cli build:configure
|
|
287
|
+
|
|
288
|
+
# Build for iOS
|
|
289
|
+
npx eas-cli build --platform ios --profile production
|
|
290
|
+
|
|
291
|
+
# Submit to App Store
|
|
292
|
+
npx eas-cli submit --platform ios --profile production
|
|
293
|
+
```
|
|
294
|
+
Note: EAS Submit requires an App Store Connect API key. Guide user through creating one in App Store Connect > Users and Access > Keys if not present.
|
|
295
|
+
|
|
296
|
+
### React Native (bare)
|
|
297
|
+
```bash
|
|
298
|
+
# Archive in Xcode: Product > Archive
|
|
299
|
+
# Or from CLI:
|
|
300
|
+
xcodebuild -workspace ios/App.xcworkspace -scheme App -configuration Release archive -archivePath build/App.xcarchive
|
|
301
|
+
xcodebuild -exportArchive -archivePath build/App.xcarchive -exportOptionsPlist ios/ExportOptions.plist -exportPath build/
|
|
302
|
+
|
|
303
|
+
# Upload via Xcode Organizer, Transporter app, or `xcrun altool`
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Flutter
|
|
307
|
+
```bash
|
|
308
|
+
flutter build ipa --release
|
|
309
|
+
# Output: build/ios/ipa/*.ipa
|
|
310
|
+
# Upload via Xcode, Transporter, or `xcrun altool`
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Native iOS
|
|
314
|
+
```
|
|
315
|
+
# Archive via Xcode: Product > Archive
|
|
316
|
+
# Upload via Xcode Organizer or Transporter
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 13. TestFlight (Recommended Before Production)
|
|
322
|
+
|
|
323
|
+
- Upload build to App Store Connect
|
|
324
|
+
- It will be available in TestFlight within minutes (internal) or after beta review (external)
|
|
325
|
+
- Internal testers: up to 100, no review needed
|
|
326
|
+
- External testers: up to 10,000, requires beta review (usually <24 hours)
|
|
327
|
+
- Recommend at least internal TestFlight testing before production submission
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 14. Review Preparation
|
|
332
|
+
|
|
333
|
+
Before submitting for review, prepare:
|
|
334
|
+
|
|
335
|
+
- [ ] **Demo account** — if app requires login, provide test credentials in review notes
|
|
336
|
+
- [ ] **Review notes** — explain any non-obvious functionality, required hardware, etc.
|
|
337
|
+
- [ ] **Contact info** — phone number and email for the review team
|
|
338
|
+
- [ ] **App-specific features** — if using restricted entitlements (HealthKit, HomeKit, etc.), provide documentation
|
|
339
|
+
- [ ] **Export compliance** — declare if app uses encryption (most apps do via HTTPS — answer "Yes" and mark as exempt under standard exemptions)
|