在 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

怀念小时候吃过的食物

怀念小时候吃过的食物

前两天下班骑车回家的路上听到了路旁有人在讨论泡馍。他们口中的泡馍应该是类似西安羊肉泡馍之类的食物。但是我却想起来了小时候吃的不一样的泡馍以及其他吃食。 不一样的泡馍 小时候我们那里普遍比较贫穷,家家户户除了过年过节基本上很难吃到大块肉。小孩子饭量时小时大,中午吃的饭,半晌就又饿了。家里有大葱或者豆糁的话,可以拿着一个馍就着就吃了。整根的葱是最下馍的,葱白部分甜又辣,葱叶里面会有像鼻涕一样的粘液,要把它挤出来才下得嘴吃。豆糁是黄豆的发酵产物,煮熟的大豆加盐发酵几天,黏丝丝的时候团成球,放到发黑就能吃了。吃的时候从球上掰下来几小块就行。豆糁是咸的,因而也能下饭。不过最妙的吃法是将豆糁和鸡蛋一起炒。鸡蛋的香气和豆糁稍微发臭的味道混在一起,形成一种独特的香味。像北京的臭豆腐一样,闻着臭,吃着香。 如果家里没葱没豆糁了,馍又很干,那泡馍就是解决饿肚子的绝好办法。将干硬的馍掰成几瓣,不能太碎小,放到瓷碗里。倒入炒菜的肉味王佐料,或者是平时攒下来的方便面调料。再提溜着暖水瓶,倒进去冒着热气的水。当然香油是少不了的,拿着油光光的瓶子,滴进去几滴喷香的香油。最后用大碗盖住,或者干脆啥也不盖,静等

By Gray
Swift Server Push Notification 配置

Swift Server Push Notification 配置

获取证书 在 Apple Developer 开发者账号 Certificates, Identifiers & Profiles 里选择 Keys。新增一个 key, configure 里选择 Sandbox & Production。下载该 p8 证书,并且保存好(只能下载一次)。 终端 cd 到证书所在路径,输入下面指令。 openssl pkcs8 -nocrypt -in AuthKey_XXXXXXXXX.p8 -out ~/Downloads/key.pem cat key.pem 得到 PRIVATE KEY 字符串,复制好。 服务端配置 服务端有多种技术栈方案,包括 Java、

By Gray
香港游记——一个传统而又现代的城市

香港游记——一个传统而又现代的城市

这是 2024 年的最后一场旅行,从北京到香港,跨越了大半个中国。去香港,一方面是想领略一下它的文化和风光,另一方面是想办一个香港银行卡,买港美股以及海外收付款。 从北京到香港,动卧是一个不错的选择。乘坐 D903 次动车,晚上八点登车,睡一觉,第二天一早就到深圳北了。再从深圳北坐高铁过口岸到香港西九龙,差不多上午九点多就能到达香港。深圳北到西九龙的高铁车次非常多,不用担心买不到票。 密集的建筑 香港给我的初印象就是——这里的楼房真的很密集。不光是住宅区又高又密,商业区的建筑物与建筑物之间也几乎只有街道相隔,很少见到大型的公园或者绿化带。土地利用率很高。这一点和北京差别还是挺大的。北京虽然也是寸土寸金,但是市内绿化面积很高,大型公园也很常见。 街上密集的建筑,让人第一眼看就知道这是香港。 旧与新,传统与现代 在香港,不同地区的风格面貌会相差很多。你既能见到破旧不堪、需要修缮的古老楼房,也能见到银光闪闪、科技感十足的现代化大厦。这种新与旧的切换,传统和现代的反差,总是能给人强烈的震撼。这正是香港的魅力所在。 维多利亚港和中环摩天轮 维多利亚港是香港的中心,是香港旅游

By Gray