半年前,我加入了一个刚刚拿到一轮融资的创业团队,负责iOS项目。早期,公司生死未卜,我们只有追求快速迭代,才能找到正确的方向。这种早期默默无闻的团队,没有工程追求,赶紧写吧。但是,在确定了方向和长远发展之后,就不能再野蛮生长了。根据我过去六个月在这个项目中的实践经验,我想和大家分享一下。代码托管:自建Gitlab早期草根团队最简单的方式就是使用GitHub。但是当团队数量增加时,使用GitHub的成本非常高。常规团队计划是每人每月9。还有一个问题就是github部署在国外,国内访问网络经常不稳定。听说一个跨国团队的代码托管在GitHub上,重要会议期间GitHub无法正常访问。好突然的父爱。还有一个缺点就是服务端不方便自己配置CI服务。如果部署在自己的服务器上,其他一些服务脚本也一起部署,就会有很大的自主权。综合之后选择了主流的Gitlab。工程师的时间比机器的时间更昂贵。一个短视的团队认为分配给工程师的设备太贵了,不如挑便宜的。好的电脑虽然贵一些,但是从长远来看节省下来的工程师的编译时间比机器贵多了。设备上,我向公司建议,应该配最新的15寸RMBP,再配个dell4K显示器。后来发现键盘鼠标也很重要,大家又给键盘鼠标补贴了500元。看到很多工程师还在用air开发,macmini也是。我为这家愚蠢的公司感到心痛。我所在的一个团队曾经使用同一台计算机用于4个终端。每次编译,我都会在南京路散步。如果晚上想上网,可以看个电影回来。早期招聘是团队发展过程中非常重要的一部分。许多早期团队低估了招聘的难度和周期。因为名气不大的团队在招人上有两个劣势:不能给太高的薪水,当然优秀的人才会在市场上比薪水。像BAT这样成名已久的公司,自然会有薪资优势。创业公司虽然有选择权,但公司的未来终究是不确定的。许多工程师也担心公司会不会在一段时间后倒闭。团队东西多,杂项项目成熟后的迭代,大多是按部就班,有稳定的节奏。每个环节都有非常细分的专职人员。早期的项目还处于成长期,很可能在项目中期会看到直播火起来,所以需要加直播。或者做的时候发现竞品有个功能,管不了那么多,下个版本上线。或者CEO路过的时候突然灵机一动,推迟了上线时间。招聘除了技术这个硬指标外,早期团队还有一个工程团队文化的问题。在一个几十人的项目中,具体一个人的积极性对于项目来说其实并不是很重要。他只是完成了工作。即使不与其他人交谈也没有什么效果。一个大项目不会因为没有人而失败。但是早期队伍只有几个人。如果一个人对团队使命的认知不一致,那么在日常行为中就会出现很多摩擦。我思考过什么是团队文化,如何描述团队文化。后来看到一句话觉得挺贴切的。文化是空气,无处不在。公司没有规定下班后需要在社交平台上回复用户反馈,也没有规定如果发现其他部门的产品有问题,不予重视或与其他部门的人沟通,或者看到一个更好的。是否要向公司提出建议?这些行为背后的支撑是团队文化。团队中的人决定价值观。综上所述,如果运气好招到匹配的技术人员,几天就可以见面,更常见的,可能需要几周时间。当然,如果一个人是仓促招来的,干了几个月后,发现不合适就走人,也会损害团队的士气。因此,考虑到项目未来的进展,需要及时启动招聘计划。当你发现日程太忙没法开始招人的时候,这时候你又要花时间准备面试,还要兼顾项目的进度,压力会很大。过渡Swift团队的其他3位同事之前没有编写Swift的经验。但是考虑到未来的发展趋势,我们的业务类型对动态性没有那么强的要求。我坚持在团队中推广使用Swift编程。我经常被问到的一个问题是,如果你想使用Swift但团队中的其他人不知道如何使用它,是否会导致项目推进的困难。事实上,如果团队中有人正确地引导他们,帮助他们解决入门过程中的问题,给他们一个过渡期。很快他们就回不去了。下面介绍一下从OC迁移到Swift的过程。先用Swift写网络层的库。通过桥接几个常用的OCModel和Swift对象。类似如下:classSwiftUser{init(ocUser:OCUser){}funcconvertOCUser(){}}经过这样的改造,如果一个新的模块完全可以用Swift来写。一开始一定要用OC思维写Swift代码。但是在熟悉了Swift语法之后,可以在审稿过程中慢慢提出更Swift的写法。有些功能需要OC和Swift互相调用,确实很麻烦。要求没有Swift经验的人来解决这些问题会让人望而生畏。因此,在项目过程中应该分配一定的时间来重写旧的OC代码。幸运的是,原来的代码比较乱,需要重写。这样随着业务的推进,Swift的占比越来越高。这样一两个月之后,大家就会逐渐熟悉Swift,这时候我们就会推广使用RxSwift等框架。理顺开发工作流程项目初期,需求有几万个。一个迭代版本应该开发多少功能?产品经理的本能就是靠脑袋。在一页上列出需求后,就意味着这是这个版本。程序员往往乐观地估计时间,做了半个月就过去了。下一次迭代的需求,UI设计,交付前的测试工作都搞砸了。后来经过讨论,确定了两周的迭代周期。在开发过程中,发现某个需求在本次迭代中无法完成,因此移至下一次迭代。每个周期阶段要做什么,大家都很清楚。两周左右发布参考用户反馈也是一个不错的节奏。这里要强调的是开发过程前期的准备工作。主要是指需求和UI图。大部分的需求设计都是围绕某个需求展开的,但是要将这个需求集成到现有的系统中还有很多周边的工作要做。例如,如果产品提供用户配置文件,则应该可以对其进行标记。所以我画了一张带有标签的草图。对他来说,这个需求的描述可能已经很明确了,但是真正落地的时候,还有其他的工作要做。例如,如何删除标签?标签有字数限制吗?如果标签重复怎么办?如果这些问题在产品的早期设计时没有明确表达,只能在开发过程中来回沟通。让有经验的开发人员参与前期的需求讨论,提出问题,对后期的开发有很大的帮助。不会用Sketch的设计师不是好设计师。我看到很多设计师遵循传统,一直用PS。然而,实际上,矢量设计工具Skecth的使用在业界已经很普遍了。现在手机屏幕尺寸不一样,如果设计不是矢量图而是位图,做响应式布局设计会很不方便。事实上,如果你习惯了使用Sketch进行移动端UI设计,它肯定会大大提高你的工作效率。但是和大多数人一样,很多设计师会觉得PS用起来挺舒服的,而Sketch从来没有用过。事实上,领导者有义务推动一些人让好事发生。在我之前所在的团队里,我一直暗示不太会用PS的设计师。经过几周的刺激,他说现在也可以用Sketch了。后来工程符号都在PS里组装好了,他也不能退货了。.当然,也有非常守旧的设计师,只能给他施加压力,让他被动改变。当时我们团队有一个四十多岁的设计师,我们也很尴尬。我当时就想,算了,如果下个月不能用Sketch出图,就准备自己跳槽吧。当然,作为一个团队,你不能只下一个指令就放手不管。熟练使用Sketch的设计师会特别关注他的学习状态,并及时给予指导。最后,他也取得了不错的成绩。迫于无奈,他发现Sketch确实更好用。还有安利一款非常好用的设计图输出软件:zeplin。直接在设计图上使用标注会很死板。程序员在查看过程中可以自行查看设计图的所有源信息,效率会大大提高。接入CI很多团队为了区分app中的环境,更改代码中的宏,每次提交前更改宏。常在河边走,怎能不湿鞋。我其实也遇到过提交到AppStore的时候,有人忘记改环境的宏了,app连上了测试环境。在这里我想说的不是在发布之前要仔细检查,而是这种情况是不应该发生的。其实通过Xcode打包手动提交也是一个有风险的过程。因为时不时的,本地会改几行代码,提交的时候本地的代码也一起提交。带来了未知的风险。我通过在Xcode中配置方案和目标来区分环境。使用fastlane完成自动打包上传的工作。结合Gitlab的CI,配置好Gitlabrunner,从此打包只需要点击一个按钮。手动操作释放的风险降低了。我们的组件使用cocoapods来管理依赖项。Gitlabrunner配置好后,组件的版本更新也放到远程工作,不再基于本地。配置webhook后,每次作业完成时,slack频道中的每个人都会收到一条消息。善用Testflight并关注beta反馈。早期,业务变化频繁。没有自动化测试,只能靠人工测试来保证稳定性。起初团队选择发布企业版的包进行测试。当然,企业用户可以轻松下载安装,但也有不少不足之处。最大的缺点是这个包和AppStore包是两个bundleid不同的包。会导致包绑定的部分功能无法正常测试,如微信登录、支付后跳转等。我们业务有聊天功能,聊天记录只存在本地。并且我们认为一个账号只能在同一个平台的一台设备上登录。这会导致用户在测试的时候账号从AppStore版本中退出,所以聊天记录就没有了。热心的用户愿意尝试我们的测试版,但要付出不应有的代价。基于这种考虑,在我的带领下,我们放弃了发布企业版打包测试的方式。相反,使用testflight测试。Testflight的使用门槛比较大。需要收集用户的邮箱地址,然后在testflight中输入苹果发出的邀请码开始测试。很多用户因为觉得麻烦而退出,运营商认为这会给测试带来很大的不便。不过冷静下来之后,事情其实并没有那么糟糕。真正对这个产品感兴趣的用户,不会因为要填写邮箱地址就放弃。那些丢失的只是普通用户。用户使用Testflight后,后续发布的测试包也会收到更新。不会像企业版那样,只能手动告诉用户我们有新的测试包。当内测活跃用户超过100人时会有质的变化。这些是活跃的重度用户。一群重度用户用你的新版本几天,至少保证核心业务逻辑是正确的。之前有人问我们,如果用Swift,不能在线动态修复严重bug,会不会引起很多问题。事实上,因为有这样的内测过程,所以很少发生严重事故。一个意外是当我们的Swift版本升级到4.0时,一个枚举不兼容iOS8设备(Xcode没有提示我们,Apple的错)。该版本也恰好是最后一个支持iOS8的版本。我们的测试用户都没有碰巧使用iOS8系统。Beta测试期间让用户及时反馈问题也很重要。如果我向您报告问题,我还需要查看应用程序版本、我所在的页面以及我的用户ID。用户的脾气也够好。我们在APP中集成了摇一摇和报错功能,操作步骤、网络请求、设备信息等有效信息将统一收集。它可以很容易地在背景中看到。告诉用户遇到问题就摇一摇,并描述问题。用户反馈后我们会收到邮件,及时反馈给用户也很耐看。摇一摇功能不对所有用户开放,只对我们可以联系到的部分特定用户开放。毕竟,每个反馈工程师都需要跟进。如果它对所有用户开放,我们将收到太多无效消息。经常看到工程师们讨论把这些开发者功能的入口藏在哪里。有的说在某个文本框输入特定的字符,有的说在某个角落点几下。我选择在通用链接中配置开发者面板的入口。这样用户就不会误触到app的任何地方,只能通过我们告诉他的链接跳转才能到达。坚持CodeReview,加强技术交流Codereview是个神奇的东西。所有受过良好教育的工程师都认为代码审查是好的。据我们所知,国外很多优秀的IT公司都重视codereview,但是在国内,很少看到一个团队进行codereview。或者代码审查在中小型团队中很少见。但我非常重视代码审查。从感性的角度来说,是一种工程师技能的传承。一个名声不好的方法,从公司的角度来看,这个项目还是可以的。但是站在工程师的角度,如果你有能力,何不帮助那些刚开始写代码的人一些指导呢?作为leader,在review的时候帮助成员成长,就看代码能不能完成功能,最后导致不同的结果。我读到一个很感人的句子。现在很多领导知道在工作中需要管理其他人,却忽略了领导的必要性。说实话,推进代码审查确实遇到了很多阻力。有队内的,也有队外的。团队外部的看法是代码审查拖慢了项目。作为核心开发成员,我每天有超过20%的时间没有可见的工作输出。有时候别人写错了,我打回去改,又过了几个小时才完成功能。团队内部遇到的问题是很多成员不理解工作背后的价值。很容易觉得我早上没有推进项目,只是坐在那里不知道该看什么。我认为我没有太多代码要提交。最终,我获得了团队的“最少代码输出”奖。就我个人而言,不做评论对我来说肯定更容易。我绝对可以控制这个功能的所有细节。就是这么写不好,也不是不能用。我也可以不向他们解释为什么这样写是不好的。让他们根据我的评论更改它。可是吃力不讨好的坚持到底是为了什么?刚开始工作的时候,在出差的路上认识了一位大学教授。当我们开始聊天时,我说我想问你一个问题。在中国古代的鞋子中,鞋底绣有花朵。别人是看不到鞋底的,这样做有什么意义。他回答说,我们做事不是给人看的,最终还是要通过自己内心的考验。这朵花绣在鞋底,别人看不到,但你自己知道。
