偶然与必然

很早以前,就想学习编程,大学,工作,研究生,再工作,种种原因,未能如愿。看过一些书,但从未真正写过什么代码,实现哪怕是最简单的功能。直到有一年,有些空闲时间,有了精神准备(放弃一些娱乐爱好,比如网上下围棋、打桥牌,还有就是玩一些单机游戏),找了一个主题和一个师傅,就开始了学习编程的过程。


我平时喜欢打桥牌,就以桥牌为主题学习编程,结合自己学习桥牌的经历,准备编写一个包含大量经典牌例的桥牌软件,用于提高自己的桥牌水平,起名为《桥牌训练馆》。


因为一点编程基础都没有,师傅推荐我用
Delphi来学习,并给了我一个Delphi 6的光盘,让我搭建好编程环境,几天后,师傅又交给我一小段初始代码,说:你在这基础上往下走,有问题再一起讨论。小段代码包括:随机发一副牌的代码,将牌显示在桌面的代码,和几张扑克牌的图片。我的学习编程之路就这么开始了。。。

我把那一小段代码打印出来,一行一行的看。不懂的先自己查找答案,实在不行,再问师傅。看懂这一小段代码后,自己尝试写代码,一行一行的写。慢慢的,自己写的代码越来越多。。。

经过大约一年半时间的艰苦学习、编程、数据录入,几乎所有的业余时间全部用于做这一件事,包括周末,没有时间陪老婆孩子上街,即便去了,也完全心不在焉。终于完成了《桥牌训练馆》的编写,基本实现了最初的想法,界面和功能自己都比较满意,看着自己写的软件在电脑上运行,如释重负,终于干了一件自己愿意做的事情!完完全全按自己的兴趣干的一件正事!


完成了《桥牌训练馆》的编写以后,又编写了一个围棋打谱软件,还尝试把《桥牌训练馆》用
VC 6.0编写一遍,但因能力所限,未能完成全部功能,只做了一个简化的版本,并不十分满意。因为工作压力和编程兴趣的下降,学习编程的事情就放下来了。这以后的时间里,没再写过什么代码,也没在这方面动过什么心思,但因《桥牌训练馆》的确花了不少时间和精力,心里总惦记着把它以合适的方式发布出去,可一直没有找到机会,随意在网上发布,又于心不忍。。。

2010年元旦,要换手机,就到上地华联对面的中复电讯去看手机,看了诺基亚N95,虽不十分满意,但也没有想过选择其他手机。正准备交钱,孩子在旁边说了一句,还不如买一个苹果手机!也许是命中注定,孩子的话对我产生了很大的影响,要不是这句话,我大概不会走上苹果开发这条路。正好,附近就有一家联通营业厅,就进去了。一看到真机,我立即被苹果手机的做工及界面吸引了,迅速交钱买了一部非合约机,iPhone 8G。回家后,打开电脑下载安装iTunes,进入苹果应用商店选择App。一进入商店,我惊呆了!这不就是我一直在苦苦寻找的发布软件的场所吗?当时就决定:我要做苹果开发,把我多年前编写的《桥牌训练馆》,发布到苹果应用商店。尽管,那时候我已经不再学习写代码n多年了,对苹果开发的环境、工具等情况也一无所知,但,我决定要做这件事情。

先是到海淀图书城,买了许多关于苹果开发的书。过五一时,去苹果在中国北京三里屯唯一的实体店,买了一台
Macbook pro,安装好Xcode,建立了一个Hello World工程,就把电脑放进包里,一个多月都没碰。只是每天翻翻书,到苹果开发者论坛看看帖子,我需要一些时间准备,技术和心理准备,因为我知道编程是一件艰苦的工作,一旦开始,就必须义无反顾,放弃休闲的生活方式,坚持到底。直到2010年6月16日端午节放假,才真正开始编程。目标十分坚定和明确,就是把我的《桥牌训练馆》发布到苹果应用商店。刚刚开始,名称本地化还不会做,就起了一个英文名称:iBridgeFun。一个星期后,有所进展,但焦头烂额,毕竟这么多年没写过代码了,而且,学习苹果编程也是用什么学什么,而且两者之间还是有些差别的,比如,全局变量,在VCDelphi里,定义后直接使用就行,而那时的Xcode,引用全局变量必须在前面加一个self,如定义一个NSString *string,那么引用时要写成:self.string。否则,你就不能得到正确的值。当然,现在代码已经不需要这么写了,可当时,我真没想到还需要加self才能引用。这种情况耽误了好几天,苦恼的是一点头绪都没有,茶饭不思,最后还是在论坛找到了答案。解决这个问题后,编程思路就打开了,后面进展就顺利得多。

真正进入开发角色以后,感觉生活变得充实了,总有干不完的事,每次关机都依依不舍。晚上常常失眠,脑子里都是代码,或是下一步该干什么,或是后面还会碰到什么奇妙的问题。


此后,写代码、解决代码出现的问题,就成了我的日常生活,即便上班,脑子里想的也全是代码,尤其是碰到问题时。

业余时间搞开发,要说对工作没有影响,那是假话,至少分了不少心。那时候,我真体会到满腔热情投入到工作中去,这句话并非空话!但自己只能尽我所能不影响工作,该上班上班,该加班加班,出差出国等。之所以买苹果笔记本电脑,就是因为出差太多,这样,办完事后,别人外出逛街看景,我就可以在房间轻轻松松的做自己的事。因为自己的工作性质跟软件开发没有半毛钱关系,所以,同事们没人知道我在做苹果开发工作。一次在办公室聊天,一位熟悉软件的同事,聊到xcode,他对xcode里面的ib连线觉得非常有意思,其他软件工具没有这种连线方式,讲了他个人对xcode的感觉。我默默的听着,其实,我用xcode做开发已经好几年了。

写的代码能够实现自己要求的功能,并完美的运行是一种享受,碰到难题经常废寝忘食,一心一意就是要尽快做好这件事情。因为有
Delphi代码的底子,转换到Objective C,尽管有些差别,但基本是相通的,关键问题解决后,写代码的进展还算顺利。代码的事情解决了,新问题又出现了,过去编写《桥牌训练馆》时,建立的数据库仅有中文的,要在苹果商店上线销售,面对世界各地的用户,没有英语版肯定不行,没有办法,只好又花了几个月的时间,将大量的中文,自己翻译成英语。因翻译工作量太大,当时的想法只是想尽快完成翻译工作,有些地方并没有仔细的斟酌。还有就是桥牌英语专业性也很强,翻译用词也经常迷惑,错误应该也很多。当时也想过,以后还有机会再修改,但事实上并非如此,此后,自己实在是没有精力再仔细检查并修改这些过去翻译的文件了。别说检查和修改,就是仔细的看一遍都不可能静下心来,真不知道那些文件自己当初是怎么翻译出来的。

当编程和文字翻译工作基本完成后,我在苹果模拟器上运行
iBridgeFun,并测试其各方面的功能,虽然,还没有完全实现在Windows电脑上的全部功能,但也基本上达到了自己认为的上线条件。我决定进行开发者账号申请,为真机测试和正式上线做最后的准备。

虽然,开发者论坛有人发了一些经验帖子,但轮到自己真正进行账号申请时,还是担心会有意外情况发生,而我又偏偏就碰到了意外。当时,苹果账号申请还是很复杂的,进入苹果账号申请页面,下载申请表。填写申请表以后,需要将申请表传真到美国苹果公司,然后等待苹果公司审核,正常情况,申请需要一个星期到十天的时间。如果没有条件发传真,还可以发邮件到亚洲苹果,请他们将自己的申请材料转交到美国。我选择后者,自己写了个英文邮件,把材料发给亚洲苹果,然后,等待审核结果。等了十来天,没有一点消息,信用卡也没有扣款信息,就发了个邮件到亚洲苹果询问情况,结果人家回复说根本就没有收到我前面发的邮件!没有办法,一切抱怨都是没用的,重发邮件,为了防止万一,又跑到可以发国际传真的地方,把申请表直接发到美国苹果公司。一星期后,终于收到了扣款短信,正式成为苹果开发者。


申请账号的这段时间,在模拟器上我对
App进行了比较充分的测试,因此,真机测试并没有遇到什么问题。但是,第1次在苹果手机上看到自己开发的App运行良好,十分兴奋,不停的点击,那些功能我实在太熟悉了,还是愿意点来点去!只要有空,就会拿出手机运行自己的App

完成各项准备后,提交到
Appstore审核,等待了一个星期,那天晚上12点以后,突然收到短信,Your App is Ready for sale!  终于成功了,前面的一切辛苦都值了。赶紧爬起来打开电脑登陆到iTunes,看着那个Ready for sale的标记,心潮澎拜!那晚基本一夜未眠,第2天走路都觉得十分轻快。那天是2010920日。第2天,打开iTunes,我的App居然上了新品推荐,晚上查看销售报表,销售量让我高兴。2010年11月的某天,具体那天记不清啦,当时,我正在国外出差,收到老婆短信,说xxxx美元到帐了。这是我的第1笔开发收入,真正的意义在于我开发的《桥牌训练馆》,确实卖给了世界各国的用户,满足了个人的愿望,实现了我的编程梦。从决定进行苹果开发,到收到苹果的第1笔汇款,将近1年时间。走完这么一个完整的流程,对一个业余开发者来说,时间不算短。回顾这段经历,我觉得如果现在再让我选择的话,也许没有那么大的勇气选择进行苹果开发了,因为,对我来说,基础太差,未知因素实在太多了。

我进入苹果开发,纯属偶然。如果没有早些年我学习编程的艰苦卓绝的经历,之所以这么说,完全是凭兴趣的,花大量的时间和精力,也不会有任何的回报,但我还是坚持把它完成了。如果没有孩子那句话对我的影响,也不会进入这个行当。两者结合,偶然就成为必然!


简单说创新


2010年,Appstore市场正进入高速增长时期,苹果用户们对App的兴趣极浓,许多人会花时间在应用商店搜索、选择安装自己喜欢的App。面对这么一个新兴的市场和新鲜好奇的用户,许多人投入到这个市场,有大公司、小公司还有一批个人,都希望在这个市场有所斩获。我2010年进入,不算早,也不算晚,但也过了随便一个App都能赚钱的时候,商店内的App数量爆发性增长,苹果公司也常发布下载量达到xx量级的新闻,记得当时还有一位中国人幸运的成为1xxxxxxxxx位下载者获得了苹果公司$500的奖励,用于购买App。形势一片大好,但并不意味着,每一个开发者都能从中获得收益。必须有所创新,或者有自己的特色,否则,难以在这个市场站稳脚跟。那时,有开发者发表了一篇《个人开发者已死》的文章,就是很好的证明。无论市场如何,都有活得很好的,一般的,快要死去的,已经离开的。

《桥牌训练馆》线以后,凭着当时的热情,我不可能就此止步。所以,接下来就是将原来编写的围棋打谱软件转换成IOS版本。打谱软件是需要保存数据的,但我那时不会使用libsqlite3数据库,桥牌的功能简化,也是因为需要使用数据库保存数据,只能放弃需要保存数据的功能,基础差就是这么无奈。当然,那时候的心情也完全被外界形势所感染,迫不及待,只争朝夕,急功近利,不管怎么说,早一天上线,就可以赚钱,功能嘛以后再慢慢加!也还有一种潜在的担心,万一别人先上了这种围棋App怎么办?有这种心态的驱使,简化的围棋IOS版本的代码很快就写完了,名称叫《围棋名人谱》,不过,自己还需要制作大量的棋谱,我的目标是把当时中日韩三国顶尖高手的棋谱收集到《围棋名人谱》中,制作棋谱库的工作量不算小,个人开发者的优势就是成本低、想干就干,不想干可以收摊,但劣势也很明显,许许多多的事情都要自己来完成,不会的要学,可以外包,但需要花钱,成本不低,反正我基本都是自己来做,好在我自己有先前做的围棋打谱软件,打完谱后把文件直接用在《围棋名人谱》中,时间周期还可以接受。

如何创新呢?《桥牌训练馆》和《围棋名人谱》在当时的Appstore,还算是稀有,桥牌软件本来就不多,这种类型的我当时就发现有一个BetterBridge功能类似,而且做成系列了,我当时看到BetterBridge1、2、3、4,每个只包括16副牌,而《桥牌训练馆》包括上千副经典牌例。桥牌毕竟是小众软件,你看看周边有多少人打桥牌就知道了,用户基数少,要有苹果手机或者iPad,要能看到并喜欢你的软件,要愿意花钱。。。等等,要卖出去一个,跟中彩票差不多吧。当时围棋App有死活练习题、定式,和单机版的人机对战这类,AI水平很低,我下载了一个日本的围棋App,算当时比较好的了,界面也漂亮,我这臭水平能让它九子以上。当然,做AI围棋,我也没那个能力,当时也没听说有AlphaGo。因此,《围棋名人谱》上线后,还是很受欢迎的,至少过去没有同类软件,现在再看看,十万棋谱不在话下,我肯定做不过他们啊,但我有早到的优势。《围棋名人谱》实际是《桥牌训练馆》演变而来的,思路是一样的,只是一个是桥牌,一个是围棋。做《桥牌训练馆》的ICON时,Photoshop刚刚会一点,做了一个比较丑的Icon,就一个红色的黑桃。在做《围棋名人谱》的Icon时,我还是下了一番功夫的,我查看了一些围棋app的icon,感觉都没有达到我想要的效果,日本那个围棋App的Icon基本是以一盘棋的图片来做的,棋盘格线基本看不清,棋子很小,我灵机一动,做一个局部棋盘,格线很清楚,棋子很大,效果不错,比较满意。这样《围棋名人谱》的icon就做好了,这个Icon,一直用到现在都没改,看到这个图标,我能想起当时画图的情景,自己的一点记忆,不想抹去。我觉得这个icon在当时也算一个小小的创新。

桥牌和围棋,都做了,自然就是象棋,喜欢象棋的人要比桥牌、围棋的人要多,应该会有更多的潜在用户。当时的Appstore在象棋App方面,也基本是以单机版人机对战为主的,我做的这种类型的也没见到。我还是按照桥牌、围棋的思路,做了一个《象棋大师谱》,唯一要注意的是,桥牌和围棋,我在Windows电脑上都有自己的软件,制作桥牌牌例和围棋棋谱很方便,所以,如何需要的话,资源更新很快。象棋就没有自己的打谱软件了,只能按网上能找到的棋谱格式来制作《象棋大师谱》的棋谱库文件,否则,更新增加棋谱将很难,当时自己的开发能力也欠缺,不如现在,桥牌、围棋、象棋如今我都有自己专用的打谱软件,是苹果电脑版的,Windows电脑我已经完全可以抛弃不用了。那时候可不行,在windows电脑打谱录入文件,再拷贝到苹果电脑上使用,现在鸟枪换炮了。《象棋大师谱》上线后,效果也不错,只是界面非常丑陋,说起来真不好意思,《象棋大师谱》上线后不久,苹果中国公司的员工(说中文的我默认她是中国员工)还专门给我打电话,要求我在一个星期内提交一些宣传图片,参加苹果公司的一个什么活动,活动名称我忘了,问我愿不愿意参加活动?对于一个开发者来说,应该是一个绝好的推广机会,就如天上真的掉下一个大馅饼一样,谁不愿意参加呢?可我没有答应,我答复不参加,我没有办法一个星期内制作所要求的宣传图片,而且我也认为《象棋大师谱》的界面实在太差了,参加这种活动不合适。我的拒绝,苹果员工也非常意外,因为这样的求之不得的活动怎么会有人拒绝参加?她在震惊之后,冷静的说:这样吧,你要真不愿意参加这个活动的话,请你给xxx地址发个邮件,说明你确实不愿意参加活动。因为,我如果不发邮件的话,她的领导可能会认为她没有联系到我,她会有责任!我立即按要求发了邮件,她确认收到邮件后才挂断电话。这是题外话,真正的创新是《象棋圣经》,一个收录中国古典经典棋谱,适情雅趣、梅花谱、梦入神机等等棋谱,在我之前,应该没有人做过,起名《象棋圣经》,我觉得这种绝对经典古谱,应该是象棋爱好者天天都需要诵读的经书,画了一个Icon,也用了象棋棋子中的红炮,我喜欢炮,也有一炮而红的意思。

当我想到做《象棋圣经》的时候,还是很兴奋的,上线以后也的确很火,上线那几天我在不能上网的地方出差,我给老婆打电话问排名情况,老婆告诉我:你的象棋圣经排第1了。可惜不到三天功夫,就被破解,并发帖广而告之:《象棋圣经》成功破解,正规渠道的销售大大影响。那时大环境就是这样,没有办法,苹果公司要应对越狱,个人开发者需要面对破解!虽然,销量大大降低,心情还是不错的,因为是大家确实喜欢我的App。在那个时候,作为一个开发者,如果你的App没有被破解过,心情也一定好不了!!!我的《桥牌训练馆》,在某网显示下载量xxxx,我以威胁的口气,给人家网站发了一个邮件,大意是:你站提供我的收费软件给大家免费下载,给我造成了巨大的经济损失,我正搜集证据,准备起诉你站。猜猜人家怎么回复我?就回了一个字:哼!

我之所以看重《象棋圣经》,道理上讲它是《象棋大师谱》之后做出来的,虽然代码难度比前者要难,因包含残局棋谱,但它是大师谱的延续,兴奋点是我把眼光放在了古谱上,而这些经典古谱,许多爱好者都愿意把它带在身边。自然,也带出了《围棋经典收藏》,一个包含围棋古谱和现代棋谱的App。《象棋圣经》在我心里有非常重要的位置,但它也留下了很大的遗憾,作为一个教训,我很难忘怀,此为后话!

完全的原创自然是很难的,就如苹果手机,这样具有划时代意义的创新,凡人就别指望了。我理解,在Appstore,在内容、设计、玩法、icon,UI、名称等等方面有自己的特色也算是一种创新。当然,如果有独到之处,虽说是小众软件,也会受到用户的喜爱,我的《桥牌训练馆》就是如此,因为有特点,所以,这些年销量一直很稳定。我自进行开发以来,一直追求有所不同,或特色。说个例子,我最近上了一个数独游戏,为什么这么多年一直没有做这个呢?太多了, Appstore不说上万,也有好几千吧!界面吧,做不过公司,你投入成本做UI,上线后恐怕不一定能收回成本。一直没做,就是没想出什么做点。直到最近我突然想到了一个好名字,我就把它做出来了,上线后销售还很好,至少在收费版和免费版都有出乎我意料的销量。这么一个普通的、多如牛毛的数独游戏,你会起一个什么名字呢?当然,我起名是面向国外用户的,其实对我来说太简单了,只是原来没往这方面想。照葫芦画瓢,我熟悉桥牌,有一个世界著名的桥牌软件叫 Bridge Baron,中文译名为:桥牌爵士。我的数独就叫 Sudoku Baron。虽然,我不能准确地理解这个名称在外国的实际含义,有多吸引眼球,但应该有贵族气息,至少不会令人生厌。从上线后的销售效果看,个人觉得名称因素起码要占80%,界面还是自己做,就一个底色加方块形成九宫图片,简单至极。代码没难度,做开发的都知道,数独到处都能找到写好的代码,直接用就行。说这个的意思,点滴都算创新,用心去想,还是会有收获的。

经验与教训

做苹果开发多年,虽然自己基础很差,经过不断地摸索、学习以及个人的积累,确实有了不小的进步。刚开始,只能做一些简单的功能,一步一步,做桥牌的AI对战,虽然AI水平一般,但还是做出来了,编程难度还是很高的。后来,陆续又做了升级炒地皮、斗地主、两副牌斗地主、拱猪、红心大战等单机对战版本。全部AI代码都是自己一行一行写出来的,代码行数最多的是升级炒地皮,代码总行数达到60万行,如果你是开发者或做编程工作的,一定知道60万行代码是个什么概念,对于一个业余个人开发者来说,几乎是一个天文数字。那时候真是夜以继日的写代码,debug,除了一股热情,还有坚定的信念,一定要做出自己的拖拉机App来。那真是激情燃烧的岁月,心情非常愉悦,不觉得累,精神的力量大无穷。。。有这么一段经历,值得回味。

经过一些历练,我写代码的能力大大增强,也有一些资源积累。过去做一个App,要几个月的时间,现在,想到一个主题的话,从开始到上线,一个星期就可以完成。写代码的工作,快的话一天就能完成。当然,这是在我熟悉的棋牌应用方面。在苹果应用商店,在棋牌App方面,无论是App数量,还是App种类,大概排名都是靠前的,我的App在苹果手机、iPad、iMac电脑、苹果Watch、Apple TV等均有上线。

几年的开发经历,获益匪浅。在编程方面进步不小,在开发过程中遇到各种问题,也能很快的处理。坚持自己的特色,遵守苹果公司的游戏规则,使我没有被市场淘汰,一直坚持下来了。自然,也有一些经验与教训,如果当时不那么着急上火的话,也许可以做得更好。

(1)坚持自己的特色

我进入苹果开发,正是苹果应用商店爆发式增长的时候,早期上线的App,已经占据了排名的前列。新的App如何才能得到认可呢?必须要有自己的特色,否则很难有立足之地。比如,我的升级炒地皮。当时有一款叫拖拉机的游戏(后来更名为升级,图标也更改了,喜欢玩升级的,估计是无人不晓,现在还在),很受欢迎,一直排名在前。我下载了其免费版试玩,界面UI不错,AI虽有bug,但有配音。根据我当时的能力,UI和配音都做不过,AI也很难做的比人家好,怎么办呢?苦思冥想,查找资料,终于想到一个做点,反主抄底。也就是,亮牌以后可以用王对或级别高的级牌反主并且炒底牌。这在AppStore是一个新的玩法,至少当时商店里是没有的。做这个App,难度可想而知,出牌种类之多,让人不知所措。AI完全自己设计,为了尽量减少bug,还做了许多用户看不到的附加功能,终于做完了,提交审核。第一次被拒绝,我看了一下被拒绝的理由,是分级错误!审核人员认为该App有强烈的赌博意味,大概是因为在名称里有炒地皮的字。上线后,有用户评论说,初看以为是房地产方面的App,让我哭笑不得。不过,下载量还是不错的,也算是一个成功的App。


(2)UI应该做的更好

我当时如果好好学习Photoshop,或者花些钱找人做App的UI的话,肯定比现在的情况要好的多。当时,并不是没有想过外包UI,也在网上联系过。可是沟通很困难,双方无法默契配合;还有就是没有互信,对方怕我不付钱,我怕不靠谱。我也下决心想尝试一次,写了详细的UI要求发给对方,还交了预付款。但对方给我发过来的图片,让我失望,完全与我希望的风格效果相背离,无法接受,建议其修改风格,并且找了类似风格图片发过去。但对方首先是要求先交修改费,他还没有给我画过一张正式的图片,就要修改费,道理上说不过去。如果再一张还不满意怎么办?一直无休止的交修改费吗?我不可能接受,不欢而散,白白损失了预付款。后来,没有再在网上联系过。现在,不少开发者自己找合作伙伴,这是一种很好的方式。我当时如果走出去,或许能找一个可以面对面交流的合作伙伴。但我错过了这个机会。当前的AppStore,即便是UI很好,也很难吸引用户的眼球,完全不可同日而语。

(3)没有把握好发展趋势

天生的对某些事情不敏感,只是一心一意的写代码,苦思冥想做什么主题,对AppStore的发展方向不关注也不了解。自己确实不是那块料,只知道埋头干活,不知道抬头看路。机会经过身边的时候,没有能力把握,这一点给我留下了最大的遗憾。前面提到过《象棋圣经》这个App,是收费的,上线后很受欢迎,各App推荐网站都有好的位置,也有在论坛求破解的。三天以后,即被破解,大家欢欣鼓舞。我索性限免了三天,下载量十分惊人!立即占据分类排名第一,也进了免费总榜前50。按照那个趋势,用户量突破百万,指日可待。可惜,我手贱,三天后又改为收费。如果当时继续免费,那么《象棋圣经》用户量可想而知,在免费排行榜肯定有一席之地。坚持到现在,意味着什么,开发者应该都知道。其实当时,各大公司都在推免费App,个人开发者的生存空间越来越小,我也感觉到了,但当时,搞不清楚为什么?后来,慢慢的我想明白了,但,机会却从身边溜走了。。。给我留下了最大的遗憾。

(4)测试测试再测试

我的单机桥牌App,iBridgeCard,中文名称:快乐桥牌。完成了我做一个带AI功能的桥牌App的心愿,我是做桥牌App的,做完第一个App《桥牌训练馆》后,就计划做的。前后历经大半年时间,在即将提交的一刻,别出心裁的加了一段代码,主要是防止App崩溃用的。原理需要简单说一下,根据桥牌规则必须每一轮都出牌,由AI算出该出的牌。如果AI有bug,那么,有可能无牌可出,这样App就可能在运行中崩溃!为了以防万一,我加了一段if语句,如果AI选出来的牌为空,则任意出一张牌。这样虽然不符合出牌常理,或者让人觉得牌打的很臭,但是,好处是不会崩溃,而且,只有极端情况才会出现AI选不出牌的情况,我自己心里有数,加这一段代码,并不担心会出什么问题。但这一段代码却意外的发生了错误,让我追悔莫及!代码是这样的:if ( cardsNum == 0 ) 然后,进入一段任意出牌的程序。早期的 universal 版本,也就是iPhone和iPad版本的代码是分开的,代码可以是一样的,但各执行各自的代码。我测试也基本是在iPad上进行的。上线后,在美国区iPhone分类排名很好,下载量也很可观。可一天以后,差评来了,有说胡乱出牌的。我看到后觉得很奇怪,在iPad上又测试了许多遍,没有发现乱出牌的情况,以为是别人胡写的评论,当时,职业差评师也是有的。几天以后,排名就消失了,差评又多了几个。引起我的重视,专门检查一下代码,这次检查重点检查iPhone用的那段代码,找出那个bug,我目瞪口呆!!!那段别出心裁加的代码,在iPhone程序内,变成了:if ( cardsNum = 0 ),莫名其妙的少了一个等号(=),本来是一个条件判断,结果成了永远为真的执行语句。一个天大的笑话,难怪用户评论胡乱出牌。当时的xcode智能程度还不能判断出这个错误,编译正常;现在的xcode可以把这类错误自动找出来,会报错的。尽管后面紧急修改了代码,由于我先前的疏忽大意,造成了无法弥补的后果,App还是从美国区的排行榜消失了。这是最让我感到心痛的一个bug。

(5)尊重用户多沟通

这个许多开发者都是这么做的,对每一个用户的邮件,我都会给予回复,不管是什么问题,都尽力详细回复。

除了尊重用户,我也尽力为用户着想。比如,我开发了记事本、家庭理财记账之类的App,有些需要设定登陆密码。写代码的时候,我就考虑,如果用户忘记密码怎么办?如果没有密码的话,便不能再使用该App了,而这类App的密码,有时候用户是随意设置的,过不了多久,或许就忘记了。我的App都是单机版的,不用服务器,所以,用户设置的密码,我根本无法获取。怎么才能让他们忘记密码以后,还可以登陆呢?我想到了一个办法,设置一个特殊密码,也就是后门。别人是无法知道的,只有我知道,而我跟用户也无法接触,所以,对用户来说,他们是安全的。而这样的好处是,如果他们忘记密码,我可以发送特殊密码给他们,让其打开App。从这些App上线以后,这类邮件就一直有,都是忘记密码来寻找帮助的。2018年春节回家过年,用手机查看邮件,又有一位国外用户发邮件表示忘记密码寻求帮助,我没带电脑回家,特殊密码根本记不住,只好先回复,告诉他我在家乡休假,让他等20天后,才能给他打开App的方法。一回到北京,我就打开工程文件,将特殊密码发送给他,一天后得到回复:it works.

也有特别喜欢我的App的热心用户,一个生活在加拿大的中国人,他很喜欢围棋。购买了我的电脑版和手机版的围棋App,只要发现bug,就会给我发邮件,并且附上截图,让我非常感动。后来,我开发了围棋狗打谱软件,无论是算法还是功能都比原来的App有了很大的提升。为了表示对他的感谢,围棋狗上线后,我发邮件告诉他,并且给他赠送推广码,希望他下载使用。可他回复邮件说,推广码他没用,他自己又购买了我的围棋狗,并且找到了一个bug,附上截图。虽不常联系,但彼此互相理解、尊重。

原来的苹果应用商店,用户可以评论,但是开发者是不能回复的,用户如果不给你发邮件,根本无法联系到用户,双方没有沟通渠道。苹果增加了回复功能后,虽然不是即时的,但至少提供了一个对话通道。我的《桥牌PBN阅读和制作器》英语名称《Bridge PBN Viewer & Maker》,一个美国用户购买后,发表了一个评论,对我刺激很大,大意是:中国人开发的App正在逐渐让消费者失去兴趣,英语原文比这要贬义的多。我不知道他碰到了什么问题,但看得出他非常愤怒。我当即给他回复,也尽量压制自己的怒火。说实在话,他的评论是对中国开发者的蔑视,严重的说是侮辱。给他连续反问了三个问题,指出了他的PBN文件可能存在的几种问题,可能会导致读取文件的错误结果。我写这个App的时候,对PBN文件格式是研究很充分的,也进行了大量的测试,我对App还是有信心的,至少知道他文件的问题要比我软件bug的问题更大。结尾时,还是很客气的希望他把读取错误的PBN文件发送给我,我测试后再回复他。写完回复后,我期待他能及时看到回复,并能够收到他的邮件。如果没有他的pbn文件,一切都无从谈起,他的评论将无法消除!那是我不能接受的。
第二天,我收到了他的回复,附件里有他的pbn文件,并说明了写那些评论的背景情况,表示如果是他的错误,他愿意修改评论。我打开一看,立即找出了问题所在。他的文件有问题,按照pbn格式标准,文件里缺少一个关键字段,该字段不能为空值,因为缺少这个字段,这副牌的记录文件毫无意义。而我的App是按照标准格式处理的,当该字段为空值时,引起程序崩溃,无法正常读取。他的问题是文件不符合标准格式,我的问题是软件没有对空值进行处理,读到空值,相当于数组越界出错。我增加了对空值忽略的处理,马上提交了更新,并回复了邮件,同时发送了PBN格式标准,美国人写的标准,以及符合标准格式的PBN文件模版。苹果审核也是出奇的快,2个小时就通过更新版本。因为时差的关系,他收到邮件,更新版本就上线了。运行正常,他很满意,很快修改了评论,客观的说明了事情经过,还给我提出了一个修改建议,希望把扑克牌的摆放顺序,调整为黑桃、红桃、草花、方块的黑红相间摆放方式。其评论原文如下:

I originally had a problem with the application that it would not recognize my bridge file. When I went to the developer's web page, I found that it was all in Chinese and I wrote some flaming review. That was inappropriate. The developer fixed the problem: My files do not have an auction. I use the pbn file to illustrate a deal before it is played. The developer fixed that "bug" overnight. That is responsive. The illustration that is created is just as it appears in the program's app description. That is satisfactory. I would like to be able to swap the minor suits so that the deal is shown with alternate colors, just as players place dummy, but it does work as described. I will find use for it.

我更新了App,这是我唯一一个按黑红相间方式摆放扑克牌的桥牌App。此外,根据他遇到的情况,我的技术支持网页,也替换为英语网页,网页设置了中文网页的链接,以便国内用户访问。过去我以为在我的中文博客里,有一个醒目的:Feel free to mail me: yu_tian_jian@163.com。就行了,而且确实也收到许多国外用户的邮件。其实,国外用户恐怕都与这位美国用户感受一致,看到满屏的方块字,头就大了。
这件事说明开发者与用户之间的沟通是多么重要。

就在前几天,我收到一个国内用户的邮件,他购买了我的苹果电脑版《象棋学士》,打开一个pgn棋谱文件报错,错误提示:该文件不符合中国象棋pgn标准格式无法打开!邮件咨询为什么,附带截图和pgn文件。我打开pgn文件一看,发现,他的pgn文件是国际象棋的棋谱文件,象棋学士当然打不开,我用我的国际象棋PGN阅读器(英文名称 Chess PGN Viewer)可以正常阅读。我回复邮件说明了情况,并且附带了国际象棋PGN阅读器打开文件的截图。我很感谢这位用户,他遇到问题,首先跟我联系,没有直接差评。就在写这段文字的时候,收到他的回复,只两个字:谢谢。

还有一个用户,他购买了我的手机版《象棋杀法练习》,发现一个bug,影响到使用,希望我能及早更新,修复bug。手机版《象棋杀法练习》有两个版本,一个是收费版,一个是免费版。由于苹果审核政策收紧,我无法进行两个App的更新。因此,我询问他用的是那个版本,也告诉他苹果现在的审核政策,他收到邮件后,告诉我他购买的是免费版本,同时,他还加了一句话,那大概你不会更新免费版本了。我及时更新了免费版本后,发邮件告诉他,版本已经更新,他提到的bug已经修复。事后并没有收到他的回复,我相信他是满意的。

(6)看似简单其实不简单

完成了桥牌、拱猪、红心大战,以及难度更高的升级炒地皮等App开发,接下来,我把目光放在了斗地主上,之所以最后才做这个大众化的扑克游戏,原因再简单不过了,苹果手机应用商店里,斗地主的App多如牛毛啊。不过,在开张不久的苹果电脑应用商店,还没有斗地主扑克游戏,我觉得可以把它做出来了,而且要快,在这个新兴的市场里,时间因素尤为重要。起名:斗地主博士。为了做好这个App,专门在网上找了一家制作音效的公司,谈好价格和要求后,在淘宝拍了其产品,一个星期后,收到音效文件。这次合作非常愉快,完全根据我的要求制作了全套斗地主音效文件,而且,在我对个别文件提出修改建议后,很快就收到了新文件。一切准备就绪,着手开始写代码,但没想到,我认为比较简单的AI,其实根本不简单。

首先,规则不同,原来AI的体系结构,全部要重新设计,本来想利用原有的一些资源,基本不行。原来认为简单,是因为斗地主只有三家,比起其他扑克游戏的四家,少一家。可偏偏少一家却是我没有遇到的难点,别的扑克游戏每轮必须出牌,无论盖还是跟,而斗地主可以:过,不要;出牌张数也是各家可以不同,上家出一张牌,下家可以出1张、2张(王炸)或四张(炸弹),这种情况适用所有的其他种类的出牌等等,这些都是与先前完全不一样的;出牌AI算法也不同。一下子,不习惯,很不适应这种规则,设计AI很棘手,原本以为可以轻松写完的代码,遇到了很大的困难。代码最终写完了,却是我觉得写的最不顺手的一个App。

如果有人想试试开发扑克牌类游戏,那就写写斗地主的代码吧,不要找网上的源代码,全部自己写,体会体会,看看是不是同我有一样的感觉。

(7)无心插柳柳成荫-马赛克 (Mosaic)等被投诉

苹果电脑版的超级贪食蛇,从准备资源到写完代码,也就不到一天的时间,上线后,居然也有许多人喜欢,太古老了,大家都怀念在诺基亚手机上玩这个游戏的年代。俄罗斯方块,Tetris,也是一款经典古老的游戏,我按最普通UI的界面做了一个,名称就叫Mosaic,因为Tetris是敏感词,苹果公司是不允许用的,Mosaic算是打擦边球。完全没有想到,上线后,在许多欧美国家分类排名第一,下载量可观,把那些早上线的、界面豪华的、立体的同类App,远远的甩在后面,这是我完全没有想到的。不过,好景不长。很快,我就收到了苹果公司转发的一封投诉邮件,一家国外买断Tetris经营权的公司投诉我侵权。枪打出头鸟,那些排名靠后的不投诉,就投诉了我这个刚刚上线的Mosaic。苹果公司对被投诉的开发者一般是要求先下线,然后处理投诉,处理完后,如果可以再恢复上线,不行就从此下线了。这个侵权是清楚的,只能直接下线,然后,邮件回复苹果。

开发者被投诉应该比较普遍,除了Mosaic,还有一个桥牌软件也因名称被投诉,完全是掉以轻心的结果。我的一个简化版的桥牌单机App,最早叫iBridgeS,后改名iBridge7,当时是模仿iPhone起的名,在清理App时,这个App本来是要直接删除的,没什么下载。后来,一念之差,更新了名称,还是模仿iPhone,更名为:iBridge Plus。根本没在意,现在也基本不再关注其他App的情况了。改名后没多久,就收到投诉邮件,国外桥牌App制作商iBridgePlus,投诉我名称侵权,一看邮件,这个App以前我是知道的,很早就上线了。人家对我的App也是很关注的,邮件里列出了我的这个App几年来名称的演变历史。怪自己太疏忽。当即将该App删除,并且回复邮件表示歉意。

前不久,收到了深圳小对象公司的投诉,看到苹果转发的邮件时,有些莫名其妙,完全不知道怎么回事。这是一家婚介公司,怎么会投诉我呢?也是名称侵权,说是我的“小对象”App名称侵犯了其公司的商标权,好奇怪。查找了好半天,也没有找到我的“小对象”App,按照邮件里给出的App ID号,终于查到了,我的一个从未提交审核的App,其中文名称确实为:“小对象”。明白了,这是好几年前,准备做的一个App,小游戏,后来不想做了,这种未上线的App,苹果没有提供删除功能,一直占着名称,早就忘了。我与深圳小对象公司邮件联系,问问到底是怎么回事?原来他们着急要用“小对象”这个名称提交App,想尽早上线,因为,名称冲突,无法提交,想通过苹果公司获得占用该名称的开发者的联系方式,以便联系协商,但苹果公司不可能给他们提供开发者的个人信息,这一点国内公司是做不到的,他们可以轻而易举的将其名下的任何用户信息提供给第3方,甚至是出卖,因而,他们只能通过投诉的方式,来取得联系。那时候,程序员苏淳茂跳楼事件正是国内新闻热点,其中就有国内某知名婚介公司的负面消息,他们大概想赶上这个热点。知道情况后,因为,我不能删除这个App,只能随意填写了一个名称,释放“小对象”让该公司使用,并发邮件告知名称已经修改,祝他们生意兴隆。

(8)想当然的后果

作为一个开发者,自己在App的选择,功能设计,操作界面等方面是有决定权的。你想做什么,做成什么样,完全可以做主,但是你的App要在应用商店发布,想当然的话,就会带来一些不良的后果。这是我在广播电视直播源Player上线后的一些体会。

广播电视直播源Player是我在娱乐类开发的唯一一款App。最早的想法就是想写一款自己用的播放器软件,看看电影、电视剧等视频,花了一些时间学习相关内容,搜集资料,不能上线没有关系,自己用就可以,这是开发者的一种虚荣心,自己的播放器,多酷啊。最后,写出来了,能播放的视频格式非常多,尤其是过去的老cd 盘片的dat格式视频,也能播放,自己非常满意。但是,在苹果电脑应用商店并不缺少这类App,与之比较,也没有什么特色,功能都相近,界面也大同小异。既然写出来了,发布到应用商店也未尝不可,就提交了,起名为:AVPlayer Universal。销量平平,意料之中。但是,开发过程中,无意中发现了一个做点,就是播放网络直播源,算一个特色,我觉得非常值得一试。但播放流畅性的问题没有解决,卡顿现象比较严重,什么源都卡,基本不能用。AVPlayer Universal上线后,开发工作仍在继续,就是解决播放网络直播源的流畅性问题,这类资料很少,能找到的一些方法都试了,不能满意。忽然,有一天找到了一丝线索,受到了启发,马上写代码,OK。找了许许多多的源,好几千个,一一测试,当然不可能24小时测试,没有大问题,而且,自己喜欢看的电视,都比较流畅,当时,北京正在召开十九大,每天边写代码边看十九大新闻,没感觉到卡。解决了播放流畅性的问题,让我十分兴奋,立即决定将App的名称朝直播源方面改,因为,过于兴奋选了个名称叫广播电视直播源,提交更新等待审核。第二天审核被拒绝了,苹果要求提供电视台的授权文件。这是不可能完成的任务,几千个台,国外的,国内的。放弃又不甘心,怎么办?提交之前,我也有些疑虑,预装的那些源地址怎么更新呢?当时对源的时效性知道一点,但不知道能有效多长时间,总之,是一个负担,不更新的话,里面预装的电视台慢慢的都看不了。苹果这一拒绝,逼迫我想出了一个绝佳的解决办法:源地址由用户定制。这样,就回避了授权文件的问题,同时,也解决了源地址文件更新的问题,即便不更新App,用户仍然可以自己更新源地址,一举两得。我为自己的灵机一动喝彩!修改代码,分分钟的事,名称也在仔细推敲后更改为:广播电视直播源Player。经过脱胎换骨的更新后,虽然已经在新品榜上已经消失了,(娱乐类的App上线量非常大),但仍然受到欢迎,下载排行一直位于分类前几位。我放松了,很少关注了,想当然了。后面发生的事情,完全出乎意料。

首先碰到的问题是很多用户给我发邮件,索要源地址文件,刚开始,我还一一回复,并且发送源地址文件给他们。后来,不断有用户提出要求,有些是过分的要求,呈上升趋势,不得不作出必要的反应。
前面我说过,我对用户的邮件都是一一回复,但有一个例外,就是广播电视直播源Player的用户,基本都是来索取源地址文件的,有些指明要那种源,还直接表示,不给就打差评。我虽尊重用户,但这是原则问题,不能妥协也没有商量的余地。只好在新浪博客上发了一篇博文,表明态度,今后凡是索要源地址的邮件,概不回复!当然,索要源文件的有些用户的确是自己制作源文件有困难,应该满足他们的要求。但用邮件发送的方式,也不是一个好办法。我就在《今后凡是索要源地址的邮件,概不回复!》的博文上发了一个源地址模版文件的下载链接,需要的自己下载,双方都省事。但,这样一个包括下载链接的博文,违反了新浪博客的游戏规则,用了8年之久的博客,2018年1月1日,在我发了一篇《祝大家新年快乐》的博文后,被永久封闭,搞的我晕头转向。我的所有App的技术支持都指向这个博客,是唯一与用户沟通的场所,没有这个博客,苹果公司也是不允许的。只能连夜赶工,紧急制作个人网页,修改技术支持链接,累个半死,最主要是心累。因为国内网站访问速度比境外的快,后来又在网易、天涯的博客发了带下载链接的博文,全部被网站删除,都违反了规则。只能回到GitHub,为了保住我的主要网页不会因为下载链接被封,思考再三,又把广播电视直播源Player的技术支持网页分离,单独一页。

广播电视直播源Player虽然受到欢迎,但还是出现了许多差评,是想当然的结果。差评的原因主要是两个方面:一是源地址定制,App本身不带任何源;而是播放卡顿的问题。为什么说,是我想当然导致的这种结果呢?

首先源地址定制是为满足上线要求而灵机一动的产物,是我这个App最得意之笔。至今,我仍然这么认为。可是,我却忽视了一些用户的习惯或想法,上线最初,我没有提供源模版文件,也没有过多的说明,比较侧重对源文件制作的说明,想当然的认为制作源文件并不复杂也不需要特别的软件,苹果电脑自带的文本编辑软件就足够用了。但是,一个典型的差评是这样描述的:表示买来软件就是想用的,不是让自己变成程序员的。后来,补充了一些说明,也增加了模版文件的下载链接,我以为这样就够了,没想到同样的差评还是不断的到来。有些用户根本找不到我技术支持网页的链接处,也让我始料未及!最新版本甚至加入了我个人技术支持网页的提示信息,早加这个信息提示,是不是会好一些呢?

播放卡顿的问题,开始我也没有重视,因为我自己常看的央视新闻等源,都还好,有卡顿的源,但我会切换到流畅的源看,一般源地址有好几个。经过一段时间的实际使用,我对源的情况,也有了一些了解。源的有效期比较短,从流畅,到卡顿,到完全失效,时间不过几天,有的源也就一天。在收集源的时候,开始只要有信号,我就收了,是不是流畅我根本不管,想当然的认为用户可以自己去选择,挑流畅的看不就行了。差评来了,做过一个专门的测试,当时,测试报告也发布在新浪博客上,有些效果,博客被封,博文没有保存,没有了。而且,当时测试的源,基本都失效了,再测试也没有必要。现在,不流畅的源就不收了,但还是不能保证其流畅性,因为,测试也就几分钟而已。目前,我有时间就搜寻一下新源补充,很简单,我自己也要看电视。

对于其他的差评,无法知道他碰到什么问题,我无言以对。在苹果应用商店,用户是上帝,体现的近乎完美。用户可以写任何的评价,无论什么内容都会被发表。但是对开发者的回复苹果是严格审核的,开发者只能用理智的语言去回复所有的评论,这种规则保证了应用商店的人气和繁荣。我很佩服苹果对这一规则的坚守,并且要求所有的开发者都要坚守,从无例外!

这一点国内网购市场无法相比。我初次在淘宝购物,就感觉被骗,我想买一些土耳其开心果,找了一商家有两种:一种是土耳其原味开心果,另一种带咸味的。描述里用很大的字强调咸味的特别闲,我原来都是在土耳其买原味的,自然就选了原味。收货以后发现根本就不是土耳其开心果,只是普通国产的,愤怒的打了一星差评:根本就不是土耳其开心果,骗人!可是,我的差评不能发表,需要得到商家的确认,感觉受了委屈无处发泄,心里憋屈。过了没多久,手机收到了商家的短信大意是:亲,你的问题可以沟通呀。我回复说:明明是国产开心果,为什么要描述成土耳其原味开心果呢?商家马上发了一个描述截图过来:亲,你看错了,我们说了,土耳其原味开心果不是土耳其的,是国产的! 我看了截图,又到淘宝网仔细看了其描述。果然是我看错了。原来在土耳其原味开心果文字描述的下方,有几个小字说明:原味开心果不是土耳其的。而在咸味开心果的说明是更大的文字:特别咸!玩的这种文字游戏!我只好认错,把差评删了。给商家回了一个短信:差评已经删除,祝你店早日倒闭! 这样的商家在淘宝上居然受到保护,我还会信任淘宝吗?此后,我就极少在淘宝购物,除非在京东上没有,附近实体店实在买不到的东西,才在淘宝下单。京东是不是也不能打差评,目前还不知道,自营的东西基本都保证品质,送货速度也是一流的快,价格稍贵,但踏实。

飞翔的小鸟

现实版的神话故事。突然什么都不想写了。。。

未来怎么走

这么多年过去了,以前是满腔热情,现在感觉有些累,开发环境也发生了巨大的变化,要不要坚持,如何坚持?我还在默默的思考。。。

返回