Dan Gardner:软件开发者兼意外的企业家。早在2008年,他需要学习PHP/MySQL,因此他构建了一个名为RunPee.com的网络应用程序。(它会告诉你电影中最佳的去洗手间时间,而不会错过最佳场景。)该网站获得了国际上的成功,并发展成为一个移动应用程序和业务,在过去的13多年里一直支持着他和他的家人。2020年,他和妻子使用Flutter从头开始重建了RunPee应用程序。他们都喜欢这个框架,并继续在今天的自由职业工作中使用它。
https://play.google.com/console/about/weareplay-us/#storyCards-NC
https://flex.apache.org
https://laravel.com
https://fluttervikings.com</context> <raw_text>0 嗨,感谢您的收听。这是It's So Widget的Flutter播客。我的名字是Hillel Korn。在每一集中,你都有机会与Flutter社区的另一位优秀成员交谈。在本集中,我们非常幸运地与Dan交谈。欢迎。嗨,感谢邀请我。我真的很感激。感谢你参加播客。那么,首先,你想分享一些关于你的背景信息吗?是的。好吧,我想我在这里的主要原因是谈论我构建的一个名为RunPee的应用程序。
这是一个应用程序,它会告诉你电影中最佳的去洗手间时间,这样你就不会错过最佳场景。我想,这就是我的成名之作。我是一个哲学和历史专业的学生,花很少的时间阅读哲学,而花大量的时间在90年代学习JavaScript和CSS。这逐渐演变成……
有点像在2000年代初期为公司开发网站之类的工作。然后我在微软Xbox担任Flash原型设计师。作为微软的Flash开发者,那段时光真的很有趣。这样的人不多。然后我辞去了微软的工作,成为一名自由职业开发者,然后
决定,我需要一些东西来增强我的作品集,我需要学习MySQL和一些PHP,我从未构建过数据驱动的应用程序,所以我想,你知道,我有一个RunPee的想法,它很愚蠢,但我想我会构建它,然后……
它突然火了,这让我和其他人一样惊讶。从那以后,它就成为我主要的收入来源。这是一个很棒的故事。真的很酷。我很好奇。所以,当你第一次发布这个应用程序时,它是立即获得成功,还是有一个建立用户群的过程?是也不是。这是2008年8月。我构建的,它实际上是一个使用Adobe Flex构建的网络应用程序。
我的意思是,就像我说的,2008年,并没有那么多……
移动应用程序。而且,呃,我构建了它,并参加了那一年在圣何塞举行的Flex 360 Flex大会。他们让我上台谈论它。每个人都像,“哦,我的上帝,太棒了”。然后是沉默,你知道的,我回家后,每天只有两个人使用这个网站。而且,呃,
它最初有点像维基百科,用户可以提交他们认为电影中最佳的去洗手间时间。这是我最初的想法,我认为这就是它的运作方式。许多人,尤其是开发者,当我解释这个应用程序的工作原理时,他们认为它是用户生成的内容。但事实证明,
数据需要非常精确。我们需要准确地知道何时以及发生了什么。所以我们实际上必须自己去看所有的电影。所以,这有好有坏。但是,是的,从2008年到2009年春天,它一直不温不火。
我心想,我会再给它一次机会。我开始频繁去看电影,以便在其中拥有一个完整的最新电影数据库。就在这时,2009年的《星际迷航》上映了,社交媒体也刚刚开始发展。我为那部电影添加了去洗手间时间,
当时我还添加了一个反向去洗手间时间。许多看过这部电影的人,你本能地会感觉到电影中什么时候可以去洗手间。当柯克降落在那个冰冻星球上时,人们会说,“哦,我想这是个好时机”。所以他们跑去洗手间。
然后他们回来,柯克正在和原版史波克说话。他们说,“等等,发生了什么?怎么回事?”所以他们完全迷失了方向。就像,“嘿,有一个应用程序可以告诉你,不要在这个时候去洗手间”。这引发了很多讨论。我尽快构建了一个移动应用程序,并在2009年7月4日发布。
从那时起,它就开始流行了。非常酷。听起来像是找到产品市场契合点的旅程,这非常有趣,对许多人来说也是一个很好的教训。我做过许多自己动手的小项目,当我回顾过去时,我觉得我不得不更加努力,并且不能过早放弃。也许我会更成功。有趣的是,你对用户行为会有某种期望,一旦你发布产品并查看人们是否使用该应用程序,它并不总是与现实相符。对。是的,这是一个关键方面。
找到一些可以成为你的布道者的用户,以及何时放弃并说,“好吧,是的,这永远不会获得关注,或者这只是时间问题?”没有人能回答这个问题。有很多东西成功了,我认为它们之所以成功,仅仅是因为它们在恰当的时间流行起来。
很多东西都失败了,但它们本可以在合适的环境中取得成功。你永远不知道。
我认为RunPee的优点在于你拥有垄断地位,这很棒,对吧?在创业市场领域,这就是你想要的。如果人们想知道什么时候去洗手间,你就是那个人。来你的应用程序吧。是的。实际上,在2012年或2013年左右出现了一个竞争对手?哦,不。他们是否复制了你作为模仿者?是的,他们完全复制了。它实际上被称为P-Run而不是Run-Pee。直到……
有人在支持部门联系我,他们说,“哦,应用程序没有更新,电影不对,所有这些乱七八糟的事情”。他们向我描述它,就像,“这不可能”。
我说,“你能给我发个截图吗?那甚至不是我的应用程序”。我现在正在为别人的应用程序提供技术支持。我认为他们意识到这比他们想象的要费力得多。我认为他们会说模仿是最高的赞美形式。没错。是的。所以他们消失了。我时不时地会有点担心,IMDB可能会完全像,“呸”。
我们会投入10万美元来解决这个问题,并将其彻底解决,每个人都会使用我们的版本。他们从未这样做过。我们实际上……我们的RunPee数据已获得AMC影院的许可。因此,如果你使用AMC影院应用程序,你也可以在那里找到去洗手间时间。有RunPee的标志,他们的版本非常……
呃,笨拙,与应用程序相比,但它提供了基本功能,这非常有趣,是的,我认为这是许多创业开发者最害怕的事情之一,你想要取得一定的成功,但当你过于成功时,它就会成为一个问题,然后你就会成为一个更大的目标,是的,当然,你知道,我不知道该说什么,这每个人都会面临的事情,所以我们都在同一条船上,呃……
做得更好。我认为RunPee成功的两个关键是,A,这是一个有趣的故事。所以我们的用户总是告诉我,就像我与我的整个家庭分享这个,我与工作中的人分享这个,完全没有提示。我相信每个收听节目的观众都能想象得到,即使你没有使用这个应用程序,
如果你乐意与一群朋友谈论电影,你会说,“哦,我的上帝,我必须告诉你这个应用程序,因为它让你成为关注的中心”。分享有趣、有用的信息感觉很好。而且它并不真正具有争议性。就像,
没有人会说,“哦,我完全不同意。你知道,我站在另一边”。这在政治上行不通,或者其他什么。就像,那不会发生。所以,是的,这只是一个有趣的分享。不仅仅是我们的用户,CNN也在其娱乐网站的首页上分享了RunPee,并在《复仇者联盟4:终局之战》上映时导致服务器崩溃。所以,是的,
耶,但是糟糕。对。我喜欢电影。我是一个超级影迷。我喜欢长电影。好吧,很好。你就在我们的目标人群中。对。
让与我们的用户互动变得非常容易。所以我们分享我们的Twitter账户,我们还有一个由其他人管理的Facebook账户,因为我已经离开了。
但是,就像我回复Twitter上的所有内容一样。如果你提到RunPee,你知道,我至少会点赞它,并向你展示,是的,我听到了你,或者这是一个问题。我总是会回复。我回复我们收到的每一封电子邮件。我还让用户可以直接从应用程序中向我发送电子邮件,这非常非常容易。
它包含了他们在应用程序中的位置的上下文。所以一件非常常见的事情是,你知道,我们在概要中犯了错误。也许是我们使用了错误的角色,说了这样那样的话,或者可能只是一个错字。就在屏幕上,当你阅读去洗手间时间的概要时,
我想我应该详细介绍一下这个应用程序的工作原理,但是有这些去洗手间时间,它会告诉你,电影的第43分钟,当莎拉说“滚出我的房子”时,你可以去洗手间,你知道,这就是你的提示。如果你去洗手间,那么你可以,
点击查看概要,并阅读你在离开时发生的事情的简短摘要。然后就在屏幕底部,它会说,“嘿,你有没有注意到什么问题?有什么反馈吗?”他们可以说,“某某没有这么说”。然后
很容易联系我。它已经包含了他们正在观看的电影、他们正在使用的去洗手间时间。所以我尽量让用户提供反馈变得尽可能简单,你知道,这帮助我们获得了满足他们需求的新功能。所以,你知道,我们添加了到IMDB和烂番茄的链接,因为人们说,“嘿,你知道,这会很方便”。而且
这是一件很容易添加的事情。我们添加了“额外内容”,因为用户说,“嘿,你能让我们知道片尾有没有额外内容吗?”我的意思是,你已经在看电影了。所以我们添加了这个功能,而且它非常受欢迎。很多人只是为了查看电影中是否有额外内容而使用这个应用程序。还有其他服务提供此功能,但它们是众包的。
我们做得非常好,例如片尾有9分钟长,有两个额外场景。其中一个在大约2分半钟后,还有一个额外场景。然后在片尾之后,可能还有一个。而其他服务只是简单地说是或否。我们提供了所有这些。额外内容没有付费墙,也没有广告。你可以,
如果你使用RunPee应用程序来查看额外内容,你将永远不会看到广告,你也不需要花钱。这是一个很棒的功能。我仅仅是为了这个功能就会使用这个应用程序。没有什么比坐在那里看9分钟的片尾然后什么也没有更糟糕的了。对,对。我们之所以这样做,是因为有些人确实像我说的那样只为了这个功能而使用它。我们没有从他们那里赚钱,但他们确实拥有这个应用程序,并且可以提醒他们与其他人分享。所以
所以我们的付费模式是你可以永远免费使用这个应用程序,并且只观看广告。你还可以选择何时观看广告,因为如果你正在看电影的一半,然后,“哦,我需要去洗手间”。
你打开应用程序,然后你的脸上出现一个视频。就像,“哦,糟糕”。你知道吗?所以我们让你选择何时观看广告。或者,如果你看了很多电影,并且想支持我们,并且不想处理广告,那么你可以每月订阅1美元。这并非适合所有人,但它作为一个选项存在。
不错。这很有趣。所以在这个公司的故事中,你已经开发了一个,使用Flex来构建移动应用程序。然后很明显,我们在这里是因为我们切换到了Flutter。所以我很想知道你的思考过程,包括,你知道,是什么促使你切换,以及你为什么选择Flutter?
好吧,是的,从2013年到2020年,我几乎没有做过任何自由职业工作。我一直靠RunPee应用程序生活。我有点渴望重返这个领域。而且Flex和Air不再有需求了。
此外,我还担心Air的未来,因为Harman已经接管了。它将得到多好的支持?这个应用程序需要改头换面。对我来说,当时我是一个开发者,而不是设计师,它看起来还可以。现在它已经用Flutter重建了,
哦,我的上帝。就像,我看到旧应用程序的截图,我说,“哦,我怎么能让它看起来像那样?”它看起来好多了。然后很明显,它的性能要好得多。更重要的是,它具有未来性。我觉得很有信心,你知道,我们可以至少使用Flutter十年,而不用担心,你知道,我们是否应该采用新的东西,适应新的东西?
在选择新框架的时候。首先,它肯定是要跨平台的,因为我不会构建两个应用程序。我对此从未感兴趣。此外,我不会编写JavaScript,因为我不喜欢JavaScript。我喜欢类型化语言。我不喜欢HTML、CSS的世界。你知道,每次我必须去修改我的
RunPee.com的WordPress博客,然后进入CSS,我都会说,“哦,这是一个噩梦”。而且,你知道,向那些这方面的专家致敬。脱帽致敬,但这并不是我想涉足的东西。幸运的是,Flutter刚刚超过了1.0版本。我的妻子实际上是第一个发现它的,
她说,“这看起来非常有趣”。我们对此进行了研究,并在Udemy上参加了Angela Yu的课程,她是一位很棒的讲师。然后我们重建了这个应用程序。从那以后,我一直使用Flutter做一些自由职业工作,以增加一些额外的收入。
酷。自从发布以来,用户的反应如何?很明显,你正在切换应用程序。我认为你更新了一个版本,他们从旧应用程序切换到新应用程序。是否有积极的回应或任何担忧?是的,是的。压倒性地积极。就像我说的,它看起来好多了。它的功能仍然与旧应用程序相同。导航没有根本性的改变。
所以这对用户来说很方便。我想我遇到的一个问题是,我非常幸运,我可能至少提前一年就预料到了这一点,那就是从数据库中获取数据用于本地存储。现在,当你拥有它时,你会认为,“哦,你在同一个沙箱中”。所以你只需要打开那些MySQL Lite数据库
数据库等等。一切都很酷。但事实并非如此。我所做的是,我在文本文件中存储了用户的ID号。这很容易找到。它位于沙箱的根目录。所以当我迁移到Flutter时,我只需要找到那个文件。我知道用户的ID号。根据他们的ID号,我可以自动登录他们
我不必像试图,你知道,弄清楚如何使用旧数据或任何类似的东西,可以无缝地迁移。这花了我很长时间来解决这个问题。呃,但是,是的,这确实使绝大多数用户的过渡变得非常顺利。呃,你知道,他们有一天打开应用程序,这也发生在大流行期间。呃,
所以每天更新的人很少。实际上,我现在仍然有人刚刚获得新版本,他们给我发邮件,说,“哦,我的上帝,我喜欢这个”。这什么时候发生的?我想现在是两年前了。让我们谈谈应用程序本身。我觉得在这个播客的每一集中,我都谈到了状态管理。那么,你使用了哪个包,或者这个应用程序是如何构建的?好的。所以,
从Flex而来,我已经为自己构建了一个状态管理系统。当我学习Flutter时,我也这么做了。我真的很喜欢它对状态管理是不可知的。它不会强加于你。所以我尝试了Block和GetX。
还有其他几个,你知道,我不记得它们的名字了,但是,你知道,如果你去阅读,如果你搜索“Flutter状态管理前五名”,每个人都会给你基本上前五名。我试用了所有这些,但都不喜欢。除了只使用setState和change_notifier的默认方法之外,你
它很简单。当我需要查找错误时,我可以跟踪代码的执行。我不明白为什么特别是Block,因为我不得不在其他项目中使用它。
我只是不明白为什么有人会使用它,但萝卜青菜各有所爱,对吧?是的,而且我认为所有不同的选项,我认为我们许多开发者在脑海中对代码的建模方式不同。例如,有些人喜欢事件结构,它是一个事件循环,用户通过点击和点击来参与这个循环,他们正在触发事件。从这个角度来看,Block与使用流和事件流的结合是有意义的。
但是对于更简单的应用程序或其他类型的应用程序,其他模式肯定更有意义。是的,我不喜欢在小部件之间传递数据,除非,你知道,像从一个到另一个,我可以接受。你知道,很明显,你构建一个小部件,它需要与它的父级通信,这很好。当你必须传递给多个小部件,并且你拥有树状结构时,它感觉就像现在……
每个小部件都像被锁定在其所在的位置一样。修剪它们有点困难。也许这只是我没有深入到使用Block的程度,但我希望我的视图知道数据,但数据不知道视图,你知道吗?例如,如果任何类似用户数据发生更改,
那么我可以发送一个通知器。嘿,关于用户的一些内容发生了更改。如果我碰巧在一个可能需要反映此更改的屏幕上,嘿,让我们再次设置状态并获取新数据。如果我不在一个包含任何用户数据的屏幕上,我不关心后台的用户数据是否发生了更改。所以这看起来是最少管道连接的方式,我想,
对我来说。是的。不,这对我来说很有意义。我认为我发现Flutter的一个特点是,如果你深入到性能级别,setState的性能可能不如其他选项。但是,Flutter通常性能非常好,以至于在更简单的应用程序中,你损失的性能你并不一定会注意到。
我认为我发现我们的应用程序是,一旦我们切换到Flutter Web,这些性能问题就会浮出水面,因为它们变得更加清晰,性能受到更多限制的地方。但在移动设备上,特别是,我发现大多数Flutter应用程序开箱即用就非常快,无论它们是如何构建的。哦,当然。是的,你真的必须搞砸才能,才能,才能获得移动应用程序的性能。是的。
就像,“哦,等等,我是否在构建中调用了那个循环?哦,糟糕。这就是为什么……就像,好吧,不要那样做。对于许多需要……的小部件,我的过程是,例如,我使用一个变量小部件作为主体,例如对于脚手架。并说它将在那里加载数据。所以在这个时候,我甚至不需要更改通知器,因为……
我将其设置为圆形进度指示器。所以这将是脚手架的主体或包含它的一个小部件。它加载并说,“嘿,默认情况下你会看到一个微调器”。然后在initState中,你调用一个异步方法。它说,“嘿,去获取这个数据”。当这个数据返回时,如果成功,
然后显示包含我们刚刚获取的数据的视图。如果失败,则显示错误。然后设置状态。所以,你知道,在这个整个场景中,你只设置一次状态。所以,是的,你知道,如果你由于某种原因,正在左右广播事件并反复设置状态,你可能会遇到麻烦。但我认为此时你需要查看,例如,
我正在用我的数据做什么?我的数据为什么变化如此频繁?伙计,让我告诉你,你也可以用Block做到这一点。因为我最近参与的这个应用程序,我们必须修复其中的一些问题。所以我认为我对Block的一个问题是,有很多方法可以真正做错。我想这可能是大多数状态管理的共同点。就像,
如果你没有正确操作,你很容易就会遇到Block的可怕性能问题。
这是一个有趣的观点。我发现当我第一次学习设计模式时也是如此。每次我学习一个新的设计模式时,我都会非常兴奋。我一直渴望使用它并应用它。我发现如果我只是编写简单的代码,它通常运行得很好。如果我尝试应用错误的模式,那将是一场灾难。这将是一段非常糟糕的代码。显然,如果你找到了合适的模式,那是最好的情况。但是当你选择错误然后继续使用它时,这可能会非常困难。因为同样,你可能会朝着应用程序真正需要的方向过度工程。
是的。并不理想。我很好奇你使用什么作为后端,以及你如何将前端与后端通信?哦,哇。仍然是运行在Apache服务器上的PHP MySQL。我实际上正在使用WP Engine。那是WordPress。它是针对WordPress优化的。这几乎是他们所做的全部工作。我将其用于runp.com。然后我有runp.net。
是用于应用程序的API。所以将来,所以这是我做过的最愚蠢的事情之一。就像,我只想回到我2018年的自己。就像,“不要将API放在与博客相同的域名上”,你知道吗?所以当CNN发布了,
呃,关于RunPee的所有这些内容,所有这些人都来到runp.com。它不堪重负。而且,你知道,WordPress是一个相当大的负担。呃,它使服务器不堪重负,你知道,它也使,呃,
应用程序API也无法连接。应用程序的RunPee API非常非常小。它只发送非常非常少的数据。所以它运行在它自己的服务器上。它自己很开心。几乎没有什么可能出错。
话虽如此,这个月,或者下个月,我正在构建一个应用程序,我将使用Firebase和AWS以及其他一些,因为我从未需要使用其他后端。
而且我觉得人们都在谈论所有这些其他选项,GraphQL。就像,“好吧,你知道,我应该构建一些示例应用程序,并了解它们擅长什么以及它们不擅长什么”。因为我现在在我的工具箱里只有一个工具,那就是PHP和MySQL,它可以工作,但可能还有更好的解决方案。所以我将花一个月的时间来尝试不同的后端来完成同一个项目,看看,你知道,什么对每个人来说最有效。
不同的东西。- 酷,祝你好运。我很想知道结果如何。- 你最喜欢的后端是什么?- 我实际上也使用MySQL和PHP。Laravel是谁?你熟悉Laravel框架吗?- 我不在后端使用框架。我只是-- - 它是一个PHP框架,用于PHP。它与Ruby on Rails非常相似。它有点像PHP的Ruby on Rails。然后我们创建一个非常简单的REST API,它可以工作。好处、坏处、优缺点。它非常快。
它非常便宜。这两个都非常好。缺点是,我认为它需要相当多的维护,以及可以维护它的人。我很幸运有一个在这个领域很精通的合作伙伴来帮助我。但是如果我只是独自在一个应用程序上工作,我很有可能会使用Firebase,仅仅是因为安心。你有一个始终可用、始终运行、不需要更新的后端。没错。我想我在开发RunPee应用程序中最大的收获是……
对后端进行版本控制。因此,对于 RunPee 应用的每个版本、每次更新,它都会拥有自己的 API,它可能与之前的 API 相同,但是,你知道,服务器上有一条通向它的路径。而且,你知道,我有 6.1 或 6.0、6.1、6.2、6.3 等等版本。所以,任何时候我想更改 API,我都可以进去将其清除并重构整个内容。我不必担心,
担心会搞砸那些尚未更新应用的用户。我正在做一个已经发布的客户项目,他们没有对 API 进行版本控制,这带来了无尽的麻烦。就像,好吧,我们不能那样做,因为那会把这些人搞砸。而我想,好吧,我们该如何修复任何东西?还有什么想补充的吗?哦,天哪。是的。
我真的很兴奋 Flutter。希望新冠疫情正在消退。我很想参加一些 Flutter 大会,结识一些其他的 Flutter 开发者。我认为这是我非常怀念 Flex 的东西之一。我仍然与许多我以前的 Flex 同事(包括男性和女性)保持着很好的友谊。
你知道,在,我认为,实际上是 360 Flex 大会开始于