跳转到主要内容

WRITING

从零到 TestFlight:一个人做 iPhone app 的完整路径

2026年9月1日11 分钟阅读曾田力
AI协作iOS教程独立开发
从零到 TestFlight:一个人做 iPhone app 的完整路径

两周里我做了 9 个 iPhone app,其中 8 个发到了 TestFlight(苹果官方的内测渠道,装了它别人就能提前用你的 app)。

这篇不是复盘,是教程:按你从零走一遍的顺序,一共五步,每一步只讲三件事——做什么、怎么知道成了、坑在哪。看完你应该能自己走一遍,至少心里有数:每一步在等什么、别信什么。

先给一颗定心丸和一句警告。定心丸:写代码是整条链上最省事的部分,最小的一个 app 只有 367 行。警告:这条链上每一环都倾向于「安静地半成功」——不报错,但也没成。

难的不是写代码,是证明你是你——以及每一步都知道它到底成没成。


一、第 0 步:先判要不要做

做什么:动手前先过一条否决线:

只是想在手机上看一眼,而且有网络——那是个书签,不是 app。

手机 app 能干而网页干不了的,只有四件事:离线也要能用、要用相机这类硬件、要住在桌面小组件或锁屏上、要往回写数据且写的时候用到手机本身的能力(拍照、Face ID)。

该不该做成 app:否决线与四条真理由
这条线是我做完前 8 个之后立的,从那以后它否决掉的点子比放行的多。

怎么知道成了:你能一口说出这个点子命中四条里的哪一条。说不出来,就把网址存到手机主屏幕——五秒钟,零成本,效果一样。

:我自己差点栽进去一次。有个网页我每天早上打开看一眼,念头是「做成 app 多方便」。停下来问:app 版比在浏览器里打开它多了什么?答案是什么都没多——少输一次网址,换来后面五步的全部麻烦。


二、第 1 步:注册账号——先做那个不可逆的决定

先选账号,再碰任何东西

苹果的开发者身份分两档:

装进自己手机给别人用有效期费用
免费7 天,到期 app 直接打不开0
付费✅ TestFlight1 年¥688/年(中国区实付,不可退款)

免费档适合试水。但有一条几乎没有教程会写的规则:每个 app 有一个全球唯一的识别名,用免费档签发过的识别名,永久归属那个苹果账号,谁也删不掉。

我的真实代价:先用旧账号的免费档试了 3 个 app,确认可行后,用另一个新注册的苹果账号开了付费会员。于是旧账号名下那两个识别名再也拿不回来——上传时报「识别名不可用」,一个 app 被迫改名,另一个干脆放弃分发。

所以这一步的第 0 小步是:想清楚付费会员要开在哪个苹果账号上,然后从头到尾只用这一个账号。这是整条链上唯一无法撤销的决定,而它发生在你还没意识到自己在做决定的时候。

缴费与等待

做什么:developer.apple.com → Enroll,选个人档(不需要公司资质),缴 ¥688。

怎么知道成了:收到那封「欢迎加入」的邮件。页面写「最长 48 小时」,我实测约 8 小时(早上 7 点付款、下午 3 点通过)。别按 48 小时排期,也别指望一定 8 小时;付完款页面一直显示「处理中」是正常的,不用反复重试。

立刻生成一把 API key——它决定后面能不能无人值守

付费通过后先别急着建 app,去后台(App Store Connect → 用户和访问 → 集成)生成一把 API key:一个小文件加两串编号。它的作用是让「上传 app」从此不需要人守着输密码、收验证码。

我卡了整整两天,就是因为一开始没做这一步:

认证三连跳:从每次都要人在场,到彻底无人值守
用密码登录,每次都要人收验证码;用开发工具存的登录会话,它会悄悄过期,过期那天所有上传一起失败;换成 API key,苹果明说它不过期,从此上传不需要人在场。

怎么知道成了:那个私钥文件在你手里,两串编号存在安全的地方。

:私钥文件苹果只让你下载一次,当场存好,别想着回头再说。


三、第 2 步:第一个 app——先跑通一屏

环境只有一条要求

装 Xcode(苹果官方开发工具,免费)。唯一的坑:Xcode 的版本必须不低于你手机的系统版本。手机系统更新的时候,报错信息完全不会提示「该升级 Xcode 了」,只给一个看不懂的连接错误。

怎么知道成了:手机连上电脑后,Xcode 的设备列表里能看到它,没有黄色感叹号。

需求不用写文档,指着一个既有的东西说

9 个 app,我没写过一份需求文档。我把自己敲过的每句话全部拉出来数了一遍——149 条,中位数 34 个字

149 条需求原话的长度分布:七成不到 50 字
超过 500 字的只有 3 条,全是我从网页上粘贴的原始材料,不是需求。

最有效的提法是指着一个已经存在的东西:「这个网页/这个程序,做成 app」。既有的东西自带三样最难讲清的信息:数据从哪来、逻辑怎么算、名词是什么意思。反过来,如果一个点子只能用文字从头描述、没有任何既有的东西可指,它多半还没到该动手的时候。

(这条对「跟 AI 协作」和「自己给自己立项」同样成立。)

铁规矩:第一屏没亲眼看到之前,不写第二屏

做什么:先只做一个界面,在模拟器(Xcode 自带的虚拟手机)里跑起来,亲眼看到它,再写下一个。

为什么:界面之间怎么跳转——底部标签?列表点进去?——是整个 app 的骨架。骨架错了,写到第五个界面才发现,就是五个界面一起返工。这个错我犯过一字不差的一遍。

怎么知道成了:你在模拟器里看到了那一屏。不是「编译通过」——编译通过只说明代码没写错字。

顺便说一句体量,好让你敢动手

9 个 app 合计 124 个源码文件、19,334 行;单个 app 中位数 11 个文件、1,600 行。最小的那个 367 行,装机能用,天天在用。

9 个 app 的代码量:中位数 1,600 行,最小 367 行
「做一个 iPhone app」的门槛从来不在代码量。

四、第 3 步:装上真机——从这里开始,「没报错」会骗你

做什么:手机连上电脑(数据线或同一个 Wi-Fi),在 Xcode 里选中它,点运行。第一次装完,手机会拒绝打开,要去「设置 → 通用 → VPN 与设备管理」里手动信任你的开发者证书——这是正常流程,不是出错了。

怎么知道成了:**在手机上点开它,并且点进第二层界面。**图标出现在桌面上不算——签名有问题的 app,图标照样出现,点开就闪退。

:从这一步起,命令和工具会「说谎」。我收集了四对「我以为 vs 实际」:

四对「我以为 vs 实际」:全都不报错,只是安静地什么都没干
没有一个报错。它们只是安静地什么都没干。

其中两个都出在「启动」上:手机锁着屏的时候,启动命令返回「成功」,实际什么都没跑起来;app 已经开着的时候再启动一次,同样返回「成功」,实际新的启动参数根本没进去。

这一步教会我整条链上最值钱的一个习惯:**判断一件事成没成,不看命令说什么,去找它该留下的痕迹。**app 真跑起来了,服务器日志里就该多一条来自这台手机的请求;没有那条日志,打印多少个 ✅ 都不算数。


五、第 4 步:接数据——三种形态,成本差一个量级

app 的数据从哪来?只有三种形态,选哪种决定了你后面一半的工作量。我的 9 个正好三种都占:

三种数据形态:纯离线 / 联网只读 / 联网读写
三条路的成本差一个量级,而看起来最省事的那条,隐性成本最高。

怎么选

  • A 纯离线:数据在电脑上生成、打进安装包。看起来最省事——不联网、不要登录——但数据一变就要重新装一次机。只适合更新频率很低的内容(档案、题库这类)。
  • B 联网只读:手机从你的服务器拉数据,数据常新,代价是要处理登录。
  • C 联网读写:手机往服务器写回数据。这才是 app 真正比网页强的地方(对应第 0 步四条理由里的「往回写」),也是坑最深的一条。

C 形态的必踩坑,原样奉上:一个 app 要把手机拍的整页照片传回服务器。手机端我已经把图压到 2.9MB,本地测试全绿。上了真机、对着真服务器传——每次必然失败。原因:服务器默认只收 1 MB 以内的上传,超了直接拒;而本地测试环境没有这个限制,所以本地永远是绿的。

怎么知道成了:C 形态上线前,用真手机对着真服务器传一次最大的那种负载。模拟器和本地后端在这件事上证明不了任何东西。


六、第 5 步:上 TestFlight——以及整条链的验收清单

做什么,三件事:

  1. 后台建一条 app 记录(App Store Connect → Apps → 新建)。整条链里只有这一屏必须人点,机器代替不了。注意 app 的名字也是全球唯一的,英文常用词基本被占光,用中文名一次就过。
  2. 上传:用自动签名,配上第 1 步那把 API key。不需要手动去后台创建分发证书——几乎所有教程都让你建,我实测:这台电脑上分发证书数量为 0,而 8 个 app 全部上了 TestFlight。证书由苹果云端代管,自动申请、自动使用,你的电脑上一张都不落。
  3. 加测试员:后台把对方的邮箱加进内测名单,或者生成一个公开链接发出去。

怎么知道成了:两个痕迹,缺一不可——后台里这个构建的状态变成**「可用」;你自己手机上的 TestFlight 里真的装到了它**。

:「上传成功」四个字不算数——它只证明字节发出去了,不证明苹果收下并处理完了。我踩过一个更阴的:上传成功、处理完成、状态全绿,但构建没有挂到版本上——后台画廊里是一个灰色空图标。没有任何一步报错,只有肉眼能发现。

最后,把整条链的「别信什么/去看什么」收成一张表。这张表就是本文的验收清单

别信什么去看什么
0 判要不要做「做成 app 多方便」的直觉说得出命中四条理由里的哪条
1 注册账号页面上的「处理中」那封通过邮件
2 第一个 app「编译通过」模拟器里亲眼看到那一屏
3 装真机启动命令的「成功」手机上点开、点进第二层
4 接数据(写回)本地测试全绿真机对真服务器传最大负载
5 上 TestFlight「上传成功」后台状态「可用」+自己手机装到

这条链上每一环都倾向于「安静地半成功」,所以每一步的验收都不是「没报错」,而是亲手找到它该留下的那个痕迹。做到这一点,写代码真的就是最省事的那部分——从零开始,两周,九个,够了。

订阅

新文章都先发在这里。用 RSS 订阅: /feed.xml

作者

曾田力

水利工程师。在这里写 AI 方法论和工程实践。

这篇写错了、写漏了,或者你有别的想法?