一个人在深圳,把App送上App Store的血泪全流程
上周五凌晨两点,我盯着Xcode里那个绿色的“Upload succeeded”提示,差点哭出来。不是感动,是终于不用再被产品经理@了。
作为一个在深圳远程办公的独立开发者,平时除了写代码、改Bug、参加线上技术分享会,最大的社交活动可能就是和App Store审核团队“斗智斗勇”。没有同事可以甩锅,没有运维帮我配证书,连测试都得自己用三台二手iPhone轮着跑——自由是真的自由,孤独也是真的孤独。
这次上架的App,是我业余时间折腾了三个月的Side Project,一个基于SwiftUI的极简笔记工具。本来只想练练手,结果越做越上头,干脆一鼓作气提交审核。没想到这一路踩的坑,比我过去一年在腾讯系公司(虽然没进去,但深圳这地方,谁还没面过几次?)听到的“对齐颗粒度”还多。
今天就来复盘一下从零到App Store上架的完整流程,重点讲那些文档不会告诉你、但会让你深夜抓狂的细节。顺便聊聊我在优化这个流程时,怎么把“简历项目”变成真正可维护、可交付的产品。
别小看“上架”,它是个系统工程
很多人以为上架就是点个“上传”按钮,其实背后是一整套资源协调 + 工具链配置 + 合规检查的组合拳。尤其当你是一个人干所有活的时候,任何一个环节出问题,都会让你怀疑人生。
我这个项目一开始只是本地跑着玩,后来想上架,才发现:
- 没有正式的Bundle ID
- 没配推送证书
- App图标只画了一个尺寸
- 隐私描述全是空的
- 连应用名称都没想好(临时叫“MyNoteBeta”)
这哪是产品,简直是技术债展览馆。
第一步:搞定Apple Developer账户与资源准备
首先,你得有个 Apple Developer Program 会员($99/年)。别想着用免费账号,那只能真机调试,不能上架。
注册完之后,进入 App Store Connect —— 这个界面我熟得能背下来,尤其是每次被拒后刷新审核状态时。
在这里你需要准备的核心资源包括:
- App Name:不能带“Beta”、“Test”等字样(我第一次就栽在这)
- Bundle ID:建议用反向域名格式,比如
com.yourname.mynote - Privacy Policy URL:必须!现在审核卡得很严,哪怕你的App不收集任何数据,也得有个隐私政策页面(我用GitHub Pages搭了个静态页,5分钟搞定)
- Screenshots & App Preview:不同设备尺寸都要有,iPhone、iPad分开传
- Promotional Text & Description:别堆关键词,Apple现在反感ASO作弊
💡 小技巧:截图可以用 Xcode 的 Simulator + QuickTime 录屏,或者直接用
xcrun simctl io booted screenshot screen.png命令行抓图,效率高还不带状态栏干扰。
第二步:Xcode工程配置——别让证书毁了你
独立开发者最怕的就是 Provisioning Profile 和 Signing Certificate。每次换电脑、重装系统、甚至Apple更新规则,都可能让你的签名失效。
我的做法是:
- 在 Xcode 中开启 Automatically manage signing(除非你有特殊需求)
- 确保 Bundle ID 和 App Store Connect 里完全一致
- 在 Signing & Capabilities 里添加必要功能(如 iCloud、Push Notification),系统会自动申请对应权限
但!如果你用了第三方 SDK(比如 Firebase、AdMob),记得检查它们是否需要额外的 Entitlements 或 URL Schemes。有一次我集成一个分享库,忘了加 LSApplicationQueriesSchemes,审核直接被拒:“App attempts to access a scheme not declared”。
还有,Build Number 和 Version 别搞混:
- Version 是用户看到的(比如 1.0.0)
- Build Number 是内部递增的整数(每次上传必须比上次大)
我习惯用脚本自动 bump build number:
#!/bin/bash
buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_FILE}")
buildNumber=$(($buildNumber + 1))
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${INFOPLIST FILE}"
放进 Build Phases 里,每次 Archive 自动+1,再也不用手动改。
第三步:性能与合规:不只是“能跑就行”
Apple 越来越看重 App质量和用户体验。光功能正常不够,还得快、稳、省电。
我这个笔记App虽然是小项目,但我还是做了几项性能优化:
- 使用
@StateObject而非@ObservedObject避免视图重复初始化 - 图片加载用
AsyncImage(iOS 15+)或封装URLSession+ 缓存 - 首屏加载时间控制在 400ms 内(用 Xcode Instruments 测过)
- 所有网络请求走 HTTPS,且 ATS 全开(Info.plist 里别随便关)
另外,隐私清单(Privacy Manifest) 是 iOS 17+ 的新要求。如果你用了任何第三方库(哪怕是 Swift Package),都要检查它是否提供了 PrivacyInfo.xcprivacy 文件。没有?那你得自己补,否则审核不过。
我用的 Markdown 解析库就没提供,只好手动创建并声明:“本组件不收集任何用户数据”。
第四步:Archive 与上传——别在最后一步翻车
一切就绪后,在 Xcode 选择 Generic iOS Device,然后 Product → Archive。
这里有几个坑:
- 确保 Scheme 是 Release 模式
- 检查 Bitcode 是否关闭(Apple 已弃用,但有些旧教程还开着)
- 如果用了 SwiftUI,确保最低部署版本 ≥ iOS 14(否则可能编译失败)
Archive 成功后,打开 Organizer,点击 “Distribute App” → “App Store Connect” → “Upload”。
这时候如果网络不好,可能卡在 99% 半小时。建议挂个代理,或者选个半夜上传(我试过,深圳晚上11点后上传速度明显快)。
上传成功后,回到 App Store Connect,你会看到新构建版本出现在 TestFlight 或 Prepare for Submission 区域。
第五步:填写元数据 & 提交审核
这才是真正的“地狱模式”。
你需要填的信息多到离谱:
| 类别 | 内容示例 |
|---|---|
| 主要语言 | English / 简体中文 |
| 支持 URL | 邮箱 or 网站 |
| 版权信息 | © 2024 Your Name |
| 分级问卷 | 是否含赌博、暴力、用户生成内容等 |
| 隐私数据类型 | 联系方式?位置?标识符?即使没有也要明确声明“None” |
最麻烦的是 App Review Information。如果你的App有登录、付费、或者隐藏功能,必须提供测试账号和详细说明。
我这次因为有个“暗色模式切换”藏在设置里,没写说明,第一次审核被拒:“Reviewer cannot find the feature described in metadata.”
第二次我直接在备注里写:
This app has no login, no payment, no backend. All data stored locally. Dark mode toggle is in Settings > Appearance. Please swipe down on the note list to see the floating button.
结果4小时就过了。所以,清晰、诚实、具体,是过审的关键。
工具链推荐:一个人也要有团队效率
作为独立开发者,我攒了一套轻量但高效的工具组合:
- Fastlane:自动化打包、截图、上传。一条命令搞定
fastlane deliver - SwiftLint:保证代码风格统一,提升可读性(毕竟以后可能是别人接手)
- GitHub Actions:CI 自动跑测试,防止低级错误上主干
- Notion:管理审核 checklist 和 rejection 历史(别笑,我真建了个数据库)
这些工具不仅提升了交付效率,也让我的项目看起来更“专业”——对,没错,这也是为了简历。毕竟,一个能完整走通 App Store 上架流程的 Side Project,在面试时比十个 TodoMVC 有说服力多了。
审核被拒怎么办?别慌,这是常态
我这次总共提交了3次:
- 第一次:App name 含 “Beta” → 拒
- 第二次:未说明隐藏功能 → 拒
- 第三次:通过 ✅
平均每次等1-2天。Apple 审核员也不是机器人,有时候加一句“Hi, this is a personal project by an indie developer in Shenzhen”反而能加快处理。
被拒不可怕,可怕的是不知道为什么被拒。所以一定要仔细读 Resolution Center 里的每一条反馈。大部分问题其实文档里都有答案,只是我们懒得看。
写在最后:上架不是终点,是起点
当App终于出现在App Store,下载量第一个小时是2(我妈和我自己),说实话有点失落。但转念一想:我一个人,从想法到上线,全流程闭环,还顺手优化了性能、规范了代码、写了文档——这不就是独立开发者的终极浪漫吗?
而且,这套流程跑通一次,下次就快多了。我已经在规划下一个项目,说不定哪天就能 quit 大厂(哦不对,我本来就没进),全职做自己的产品。
如果你也在深圳,一个人敲代码到深夜,不妨试试把你的Side Project送上App Store。过程痛苦,但完成那一刻,你会觉得——值了。
对了,我这个笔记App叫 InkNote,免费无广告,欢迎下载体验(不是打广告,是真的想找用户反馈 😅)。
附:关键Checklist(自用版)
- Bundle ID 与 App Store Connect 一致
- Privacy Policy URL 有效
- 所有设备截图已上传
- Build Number 递增
- 隐私清单(Privacy Manifest)齐全
- 审核备注写清楚隐藏功能/测试路径
- 关闭调试日志和测试代码
一个人的战争,也要打得漂亮。

评论 0