在 App Store 上架了第一款软件

在去年的年终总结里,我定下的 2024 年目标之一就是在应用商店上架一款软件。作为一名软件工程师,做出来一个自己的软件并上架到应用商店,是一种无形的荣誉。

在 App Store 上架了第一款软件
Photo by Mariia Shalabaieva / Unsplash

在去年的年终总结里,我定下的 2024 年目标之一就是在应用商店上架一款软件。作为一名软件工程师,做出来一个自己的软件并上架到应用商店,是一种无形的荣誉。

在 2024 年 1 月 1 日,我订阅了 Apple Developer Program,将刚开始不久的项目连接到 App Store Connect

11 月 27 日,我的软件正式版审核通过,被批准上架 App Store。

开发和上架历程

软件创意

Float Translator (以下简称 FT) 是一个 macOS 翻译软件,支持输入翻译和划词翻译。做这个产品的初衷是解决快速翻译外文资料中的单词短句的需要。基础功能实现起来不难,我花了很短的时间就做出了雏形。后来想到自己有一个上架软件的目标,就不停地优化软件的功能和设计,为上架做准备。

市面上有不少类似的产品,比如好评如潮的 Bob ——我和它的作者还是前同事。我并不渴望某一天 FT能和这些优秀的软件分庭抗礼,也不想着能靠它挣到钱。我只是希望它能在学习工作中帮到我和用户。

开发历程

从开始做 FT,到上架,历时近一年时间。这倒不是技术实现困难,耗时点在于可投入的时间少,设计和审核时间长,以及自己的懒惰。

我有本职的工作,并不是一个独立开发者。上班时根本没有时间和机会去做自己的项目,只能下班后或者周末有空余时间了才会去推进。再加上周末往往会有各种事情,比如去周边城市旅游、朋友聚餐等,自己的拖延症,所以能投入到 FT 项目的时间少之又少。

整个 FT 项目的推进流程是这样的——初版 UI 设计,实现基础翻译功能,实现快捷键功能,支持切换语言,实现划词翻译,优化网络速度,上架 TestFlight 内测,支持存储翻译历史,「设置」和「关于」页面设计重构,用户引导,应用内购,尝试上架 App Store,不停地解决审核问题。前面流程的一些功能实现和界面设计的难度稍小。应用内购和上架 App Store 对我而言比较难,因为我并没有接触过内购和上架,需要不停地学习和改进。

上架历程

一款应用上架前最好先走几遍 TestFlight 内测和外测。内测就是开发者团队内部的测试,需要账户管理员将内测测试员添加到团队里,安上一个职务(比如销售)。外测是比较正式的测试版了,非开发者团队的人员也能通过 TestFlight 下载你的测试版软件。内测基本上不咋审核,外测审核严一些。但外测也不会像正式上架的审核那样,把软件里里外外翻一遍。

我倒是希望外测能再审核严一些,这样就能早一点发现上架的问题了。比如我的软件名字问题——我的 FT 一开始叫 Pocketize,中文含义大概是口袋翻译(一开始备案也是按这个备的),是我随意起的,最初的软件图标也设计成了一个口袋样式。我应该一早就想到它可能会和很多软件或产品有名字冲突的。直到上架的时候,审核员才告诉我,我不能用这个名字,存在「Guideline 4.1 - Design - Copycats」 问题。我不得不在 Xcode 和 App Store Connect 中修改软件的名字(注意不要改 bundle identifier),重新设计软件的图标。一来一回,耽误了不少时间。

对于需要注册登录的软件,开发者需要向审核员提供测试账号。FT 不需要注册登录,也就不需要提供。某些软件公司会提供一个特殊的测试账号,登录后会展示特意给审核员看的内容,以此规避某些审核问题。

像我这样初次接触 App Store 审核的人,一定会对审核员的各种奇葩问题感到惊讶和无奈。下面是我遇到的一些审核问题。

应用商店审核记录

Entitlements 存在一个或多个用不到的功能

我的 entitlements 设置了一个用不到的 「com.apple.security.network.server」,删掉就行了。违反的规则是「Guideline 2.4.5(i) - Performance」。

会员功能描述不清晰

Your app uses auto-renewable subscriptions, but it does not clearly describe what the user will receive for the price.

这个改起来也比较简单,在付费墙页面注明成为会员后拥有哪些权益就好了。审核员会贴心地告诉你,付费墙需要展示哪些内容。

违反的规则是「Guideline 3.1.2 - Business - Payments - Subscriptions」。

应用元数据缺少 EULA

The app metadata must also include functional links to the privacy policy and Terms of Use (EULA).

我以为在付费墙上面贴上隐私政策链接就好了。但是审核员说还缺少 Term of Use (EULA) 链接。这个链接使用官方提供的就可以,你只需要把它放在显眼的位置——付费墙和应用描述里。

我在这个问题上卡了很久,提交了多个版本都被打回了。最开始并不知道需要把 EULA 链接放哪,后来看了网上前辈们的攻略才知道需要把链接放在应用描述里。

违反的规则也是「Guideline 3.1.2 - Business - Payments - Subscriptions」。

技术支持链接不合格

The Support URL provided in App Store Connect does not direct to a website with information users can use to ask questions and request support.

我在 App Store Connect 上面放置的技术支持链接指向的是软件的官网,虽然上面也标注了我的邮箱和其他的联系方式(图标形式),但 Apple 认为这并不是一个合格的技术支持网站,用户不能看到有效的联系信息,也无法在网站上留言。

后来我专门写了一个简单的技术支持网页,注明了我的邮箱和电话号码,并且还贴了我的博客页面,博客页面是可以通过评论联系我的。这样就通过了这一项的审核。

违反的规则是「Guideline 1.5 - Safety」。

软件名字和其他流行的软件有相似的地方

Your app's metadata contains content that is similar to third-party content, which may create a misleading association with another developer's app or intellectual property.
Specifically, your app's name includes references to PocketSize.

违反的规则是「Guideline 4.1 - Design - Copycats」。

上面也提到了,FT 一开始叫 Pocketize。审核员说 Pocketize 和别的软件或者第三方品牌有冲突,而且还举了个例子——PocketSize……

我在应用商店里搜索 Pocket,确实能搜到很多名字类似的软件,而且有一个还和我的软件图标很相似,都用口袋作为图标主体,巧得很。所以我不得不更换软件名字,重新设计图标。起名字真的是一件很费神的事情。

总结

做一款软件是一个持续学习的过程

你会学习到各种知识,包括技术、设计和营销。

完整地做一个软件,是和工作中做一个业务需求有很大差别的。在公司里,尤其是大厂,做一个业务需求或者技术需求,用到的技术知识基本上是自己已经熟悉掌握的,很少有机会接触到新技术。某些比较保守的公司,还会限制你使用新技术,让你只能用老旧的技术缝缝补补。而自己做一个软件,会接触到各种新知识,遇到很多新难题。你可以随心所欲用新技术,没有人会约束你,Apple 甚至鼓励你在软件里应用新技术。

在这个过程中,你会慢慢发现,设计和营销对于软件也很重要。用户交互不友好的设计,吸引不到新用户的营销,会让你的劳动变成一场空。如果你想要成为一个独立开发者,或者想创业,那么就不要把技术看得那么重。做技术的人往往会有一种错觉,认为自己技术非常厉害,做出来的产品也会备受欢迎。但一款产品的成功,很少是因为技术,而是依靠出色的产品设计、优秀的用户交互体验以及能不断吸引新用户留住老用户的营销。

选好方向,做好调研

在你想要做自己的软件之前,先做好调研。至少回答「独立开发者的三问」中的核心问题:

  1. Who are customers? 用户群体是那些。
  2. What’s the problem? 解决现有用户的什么问题?
  3. What’s the solution? 一句话说明你的解决方案。
「独立开发者的三问」—— YouTuber 李自然说的视频 https://www.youtube.com/watch?v=u6mVi_wZs5E

调研充分,方向正确,是一个软件成功的基石。

个人项目也需要项目管理

软件研发不是一个短期就能完成的任务,是一个需要长期管理的项目。做好项目管理,一方面能让目标实现起来更加清晰,另一方面也能提醒自己有哪些任务待完成、任务的上下文是什么。

我目前用 Notion 做个人项目管理,开发过程中的每个功能细节都被拆分成了若干任务。如果内测或外测时发现了 bug,就在 GitHub 上给自己提一个 issue。

先设计再开发

在开发前,一定先把设计稿定下来,哪怕是随便画的。这样开发时才知道自己要做一个什么样的界面,会在心中有一个目标。没有设计稿的开发,就像是用代码在画草图,会导致你一遍又一遍推翻之前的代码,做许多无用功。

先上架外服,再上架国服

在国服商店提交审核前需要走 app 备案,备案需要提供软件的名字、介绍以及官网链接等信息。而这些信息可能会被应用商店审核员指出不合规,需要你修改。修改后,你的备案信息也需要进行同步变更。所以不如一开始先不上国服,等在外服改完问题、被批准上架后,再在国服走备案和上架流程。

Apple 平台非常适合个人开发者

Apple 向开发者提供了很多工具和学习平台,比如 Developer 软件、App Store Connect、CloudKit、SF 符号、各种设计模板等。可以说是给开发者准备了一切必要的工具,只等你实现自己的 idea 了。

新产品在路上了

FT 上线后,我准备将精力放在下一款产品中了。下一个会是个移动端软件,想法已经有了,准备开始产品设计。期待明年能在 App Store 中上架。

Read more

《漫步华尔街(第12版)》读书笔记

《漫步华尔街(第12版)》读书笔记

股票分析 基本面分析 * 基本面分析的四个基本决定因素 * 预期增长率 * 复合增长(复利)对投资决策有很重要的意义。 * 一只股票的股利增长和盈利增长率越高,理性投资者应愿意为其支付越高的价格。 * 推论:一只股票的超常增长率持续时间越长,理性投资者应愿意为其支付越高的价格。 * 预期股利支付率 * 对于预期增长率相同的两只股票来说,持有股利支付率越高的股票,较之股利支付率低的股票,会使你的财务状况更好。 * 在其他条件相同的情况下,一家公司发放的现金股利占其盈利的比例越高,理性投资者应愿意为其股票支付越高的价格。 * 特例,很多处于强劲增长阶段的公司,往往不支付任何股利。这时候不满足「在其他条件相同的情况下」。 * 风险程度 * 在其他条件相同的情况下,一家公司的股票风险越低,理性投资者(以及厌恶风险的投资者)应愿意为其股票支付越高的价格。 * 市场利率水平 * 在其他条件相同的情况下,市场利率越低,理性投资者应愿意为股票支付越高的价格。 * 举例,银行存款利率

By Gray
2025 端午日本九日游

2025 端午日本九日游

从日本回来后就一直忙个不停,忙着搬家和工作。这周末终于有时间回顾和记录一下日本的旅游行程。 这次出国游是年初就规划好的。端午节假期三天再加上节后请假四天,以及周末,总共能休 9 天。5 月 31 号出发,6 月 9 号凌晨的航班飞回北京。 出发前的准备 机票和酒店 越临近出发日期,机票和酒店就越贵。所以我们早早地就把机票和酒店定了。 去程机票订的山航,青岛转机,5 月 31 号从北京出发抵达青岛,在青岛玩一天,翌日早上从青岛飞往关西机场。回程机票订的海南航空,从东京羽田机场直飞北京,是凌晨两三点的红眼航班。 本次行程要去关西(京都、大阪、奈良)、关东(东京、富士山)。关西三个城市很近,一直住在京都即可,从京都往返大阪和奈良。关东就住在东京。京都的酒店订在了京都站附近,出站走几步就能到,交通非常便利。东京的酒店订在了马喰町附近,附近有很多地铁线路,包括浅草线、

By Gray
2025 关税危机中学到的投资经验

2025 关税危机中学到的投资经验

充足的现金流很重要 好的买入机会不会每天都出现,但当它出现的时候,你最好还有筹码可以投入。 有些人手里握不住钱,一有闲钱就赶紧买入基金、股票,生怕错过了机会,让钱白搭手里。市场是疯狂的、充满变数的,尤其是在特朗普上台后,一句话就可能让股市涨停或跌停。那些专业的理财投资机构尚不能预测市场,何况我们这些散户呢。在不稳定的市场中,我们要学习巴菲特,备好现金,耐心等待买入(抄底)机会。 不要提前打光子弹 美股标普 500 指数从 2 月中旬到 3 月中旬累计跌了约 10%。如果这时候你觉得已经跌了很多,可以 all in 抄底了,那么你就会错过 4 月上旬的那次狂跌——一周跌了约 10%。没有人能预测市场,除了此刻的股市指挥家特朗普。散户们能学到的经验就是「永远不要提前打光子弹」,你以为的谷底其实只是个半山腰。 相信自己,保持耐心 在美股大跌的时段里,小红书、v2ex

By Gray