如何在20小时内撰写出色的VKontakte新闻提要

大家好! 最近,VKontakte移动挑战赛举办了比赛,我的作品获得了大奖。 根据第二阶段的指示,有必要开发用于移动设备的新闻提要,主要评估标准是平滑滚动和后期加载。 当我参加比赛时,我决定不管最终结果如何,我都会写一篇文章,介绍实现录音带的方法以及比赛中我的情感和感受。 我做到了 在猫的指导下,讲故事模式下开发新闻提要的技巧和窍门。



关于比赛


首先,值得介绍一下比赛。 据我所知,VKontakte每年为移动开发人员组织此类活动。 我本人已经参加了2012年和2013年。 任务分别是聊天和图像过滤器的开发。 2013年,我设法进入最后一轮并赢得100,000卢布,对我而言,这对于4天的有趣工作来说是一笔非常不错的数目。

而且,在社交网络上看到广告后,我决定需要尝试一下,因为很酷的事情是向自己证明您仍然可以在很短的时间内编写高质量的代码。
比赛分为两个阶段:在第一个阶段中,建议通过30个问题的测试,解决2个奥林匹克问题和一个高质量的问题(即解决方案是以文本的形式表示您的一套想法)。 在第二轮的1000多人中,只有112个通过了(我们只是在谈论iOS,而在Android上的价值略低),主要阶段开始了-应用程序开发。

分配任务时,您必须制作一个新闻提要,自己编写与VK API的集成,该提要在所有设备上都应该非常流畅,显示内容有一定的要求(带有图像和轮播的帖子,喜欢,分享的计数器,观看次数以及最小化能力)并在特定条件下部署该职位)。

布局在Figma中进行布局。 这对于竞争是一个不错的选择-由于活跃用户的数量,因此立即感到竞争(甚至在周六被淘汰,因为超过了50个连接的同时限制)。

总的来说,竞赛的组织工作很顺利,除了以下几点:任务发布后,布局链接立即被破坏,然后,正如我上面所说,上周六,Figma的入口被堵住了(这个问题很快得到修复),好了,赛后花了一段时间期待结果。 但是所有负面因素都消除了类似的情况:


胜利计划与战略


如果您参加比赛或想尝试,这是一个非常重要和有趣的障碍。 在参加之前,我建议大家考虑一下您追求的目标以及想要获得的结果。 在开始比赛之前,我自己决定要赢得比赛(即获得奖金)。 为了做到这一点,您需要一个策略:


以下是获胜策略的公式(在我看来,这是通用且简单的,但是我相信大多数参与者不会遵循它):

  • 仔细阅读作业 。 几个小时后,再读一遍(我第一次没有意识到任务时遇到了几次情况)。 还有两个小时的交货时间,以防万一。
  • 撰写问题并向组织者询问 (通常,分配要求没有考虑很多情况,或者暴露得很肤浅)。 我就是这样做的,以“您的选择”的方式获得答案。
  • 制定项目计划。 是的,参加比赛或黑客马拉松是一个项目。 该项目具有目标,时间表,资源和预算。 时间受到严格限制,并且不可能结束变更。 无法邀请其他人-比赛不是团队比赛。 您只有自己的人。 /小时。 立即确定您愿意花多少钱(仔细想想它将花多少钱去睡觉,进食,去势,休息,是的,由于无可奈何的时限而来的无助感和疲劳和神经,您的生产力将下降)。
  • 该计划应包含任务,任务的优先级和权重 (我使用的估算值为1、2、4、8)。 评估包括持续时间,不愿意执行评估以及潜在风险(复杂性,难以理解的条件,没有此类开发经验等)。 接下来,您拟定详细的计划(或路线图任务)-首先是最重要和最复杂的(最后让它容易理解)。
  • 选择一些大的间隔或里程碑 (几天很棒-我们有3天)。 然后,当您遍历每一个程序时,请查看您的工作计划,分解任务,对其进行排序,最重要的是,将已经完成的任务愉快地划掉。
    现在的建议(我就是这样做的):仔细查看任务的制定方式,无论它包含“必需”还是“其他”。 对于“其他”项目的评估标准是什么,即 他们是否将克服“强制性”部分中缺少的未实施要求。 我对此表示怀疑。 因此,请关注“必需”部分。 对于我自己,我通常刻意删掉“高级”部分,甚至不打算开始。
  • 实施时,请注意细节 。 例如,如果任务有很多界面形式,则按照它们在布局上显示的方式来进行操作。 注意缩进,字体,阴影,行距等。 这肯定会为您增加准确性和一致性的要点。 顺便说一句,在Figma中,与Zeplin不同,它导出的设置非常广泛,例如,您可以获得良好的NSAttributedString。

该任务在周四至周五晚上开始。 星期五是工作日,没有机会也不想参加工作比赛。 因此,在星期五晚上下班后,我首先进行计划,评估和计算我可以花多少时间。

最初的计划如下:
时间任务
星期五4小时授权,获取配置文件和磁带的数据。
周六9小时磁带的原型,其中显示有不同高度的红色方块,通过拉动刷新将其加载到顶部,并无限地加载到历史记录中,准备所有模型和服务(使用API​​,请求缓存,图像缓存)。
周日9小时输出实际数据(文本,单个图像和轮播),点赞次数,观看次数以及按布局进行最终调整。

磁带实施技术


万岁! 先生们,开发商们,您找到了正确的障碍。 在这里,我们将讨论任务主要部分的执行-新闻提要。

通常,如果我们脱离接触,则新闻提要只是一个应用的实现,通常,我们将讨论创建异构实体的列表(也就是说,每个实体都可以有自己的显示,这需要额外的计算和自己的高度,即使显示了帖子,它们也可以动态更改) ,再加上列表可以通过“拉动刷新”进行更新,并从下方无限加载数据。

这是我决定首先解决的一般问题。 第一步是分析现有解决方案。 您需要专注于最强的应用程序,因此我选择了3个应用程序进行比较:Vkontakte,Facebook,Instagram。

因此,我想对6个最严重和最关键的问题进行研究:

  1. 拉动刷新(添加到列表的顶部)
  2. 平滑的历史记录加载(添加到列表的末尾)
  3. 快速滚动(或者用手指,我们在摩擦力允许的范围内使磁带加速)
  4. 滚动到顶部(积累一个大故事,然后单击状态栏)
  5. 帖子是否有动态披露(增加),动画是什么
  6. 磁带如何在几乎完全丢包的模式下工作(开发人员->网络链接调节器->不良网络)


总的来说,所有应用程序都表现良好,但是我仍然注意到一些问题。
例如,请查看如果在更新过程中不松开手指并轻轻拉起色带,则VKontakte中的“拉动刷新”行为是如何表现的(请参见左侧的gif)。

您是否也看到了这一飞跃?

Instagram和Facebook没有显示这种行为。

后期披露也存在明显差异。 对于Facebook和Instagram,这是通过平滑的动画发生的,而VKontakte只需单击即可更新大小。



因此,我们的任务是进行平滑滚动,下载帖子并通过动画进行显示。

第一步是选择一个概念并在红色正方形上创建原型(我想知道为什么我总是凭直觉为原型选择红色。每个人都是这样吗?)。
我提高生产力的主要想法是放弃苹果多年来引入的所有风吹草动,而实际上回溯到iOS 3的开发。这意味着:

  • 拒绝AutoLayout(是的,它很慢,不相信它-我可以在评论中证明这一点)
  • 拒绝自动计算表格单元格的高度

结果,选择了以下概念:



让我们更详细一点。

在主线程中,我们更新界面,处理用户操作(向下滚动并拉至刷新,单击帖子以增加帖子),并触发用于接收和准备数据的服务模型。

API调用 。 一切都很简单-配置了NSURLCache的NSURLSession。 重要的是,在载入历史记录时,我们使用缓存,而在刷新时禁用它。 正是我在VK和Facebook上发现的这种行为。

解析和创建模型 。 这是处理特定请求,引发错误并返回包含数据的传输模型的逻辑。

表示模型的计算 。 优化性能的最重要步骤。 在这里,传输模型通过PostModel后缀转换为实体。 ViewModel存储用于显示的完全准备好的数据-AttributedString,计算出的像元高度(对于2个状态:折叠和展开),全名作为字符串,日期字符串(已从DateFormatter转换)。

只有在那之后,数据才返回到主流。 在Swift上实现这种逻辑非常方便和简单。 我们制作ViewModel结构。 传输到新流时的结构将被复制。

准备好优秀的概念,现在让我们谈谈输出机制本身。

首先,您必须选择要在磁带上实现的磁带-UITableView或UICollectionView(肯定没有足够的时间分配给您的实现)。 显然,UITableView适合列出输出,但是我非常担心在从顶部,底部扩大列表以及增加内容单元格是否会出现问题。 因此,我决定从简单到复杂-即 如果UITableView没有问题,我们将其保留。

我决定的第一件事是决定是否要刷新。 为了实现此模式,有一个UIRefreshControl。 大约5至6年前,我曾经使用UIActivityIndi​​cator并更改表的contentInset来编写实现。 因此,请不要立即这样做! UIRefreshControl具有方便的紧凑型界面,并带有拐杖云,您一定会做出这些。 使用它非常简单:



但是,使用它时,很明显上面显示的VK客户端问题是从何而来的。 看来它们存在于组件本身中。 我迅速尝试寻找可能的原因以及解决方案。

互联网提示说( 这样 ):

  • 在调用endRefreshing时检查控件是否现在已更新(isRefreshing)
  • 完全使用UITableViewController(因为在这种情况下,将调用魔术私有方法)

我尝试了这两种方式-我没有任何积极的效果。 我很沮丧,但决定不浪费时间继续前进。 顺便说一句,如果有人知道如何克服这个问题-请在评论中写。

下一步是从下面实现数据加载。

刚开始我并没有变得很酷-从下方加载时出现了严重的滞后(我显然从表中跳了contentSize):


这真是个地狱:-)有了这个结果,您肯定不会赢。 但是快速搜索给了我一个我忘记的绝妙线索:



和瞧:


剩下的决定如何动画化细胞的高度。

我想到的第一个想法是沿着visibleCells运行并增加动画块的高度。 但是,即使在分析阶段,也应该放弃这个想法-问题是,有必要同步UITableViewDataSource中指定的高度,并使用contentSize做一些事情(Apple强烈建议这样做)。

我想到的第二个想法是正确的-UITableView具有可以在动画块中执行的insert / reload / delete方法:



不要忘记在heightForRowAt中,我们还需要添加一个新高度:



一切似乎都可以,但还不完全! 在员额部署的动画中,有一个微妙的地方。 在Intagram或Facebook中寻找文字-随着高度的增加,文字会立即平滑显示。 怎么办 逐行渲染? 如果达到NSTextContainer的级别,那么可能会出现类似的机会。 但是在我看来,一次显示所有文本并不是一个坏主意。 只需将clipToBounds设置为superView,UILabel将位于其中,显示我们的文本。 而且这种方法行得通! 哦,这个动画给了我很多启发,第二次吹响了风。 毕竟,VK的本机客户端中没有这样的动画。 所以她应该增加赢的机会:-)

磁带实施中的其余细节并不是很有趣。 但是您可以在评论中询问他们。 布置代码没有错。 这是-github.com/katleta3000/vkmobilechallenge 。 很抱歉,我没有梳理,并且某些地方有魔术数字(但这是一场速度竞赛,我不得不牺牲一些东西)。 顺便说一下,您可以在那里进行提交(名称非常清楚)。

您可以在这里看到结果-www.youtube.com/watch?v=Md8YiJxSW1M&feature=youtu.be (质量损失严重,但比gif演示完全平滑的滚动效果更好)


统计,结果,结论


比赛一直都在计时。 出现了20个半小时的纯编码时间。 跟踪时间有两方面的作用:您记得,抽象单位有估算值,所以到最后一天的中途已经有了很好的跟踪统计信息,可以更准确地计划其余的最终任务。 其次,有可能确定并证明“一次集中注意力”的模式。 每个维度都是一个新的迭代,因此事实证明,我有68个迭代的代码编写。 如果您平均,您将获得18.5分钟。 但是实际上,在迭代的第一天,平均需要25分钟,而到第二天结束时,平均每个需要7分钟:-)您开始发疯,变得非常紧张,疲倦,性能下降。 这样的数据下次会很有帮助。

我个人使用了Hourly程序(您可以下载并试用)-简单地解决了必要的任务(甚至自己开发):

在不错的奖励中-对于每个封闭的难题,您都会看到一些非常令人放心的屏幕,如下所示:


有趣的是,在完成“ VK移动挑战赛”任务后,出现了以下屏幕:


是的! 事情就这样发生了:-)我们继续研究结果。

我们不要拉桃子作为长毛绒。 桃花(谁不知道)是猫的名字-VK的主要特征。 很酷的礼物商品:


我获得第四名,得到17.5万卢布。 (是的,您可能已经在Habra-kat上烧过了照片)。 是的,我当然很高兴。 我达到了我的目标:-)毫无疑问,这真是令人愉快。

最后,我想对vkontakte表示感谢-毕竟比赛很酷而且组织得很好。 我建议所有读者参加挑战和黑客马拉松-这是挑战自我并与全球顶尖开发人员(或者至少是说俄语的社区)竞争的一种好方法。

Source: https://habr.com/ru/post/zh-CN432356/


All Articles