【CSDN编者按】很少有文章,介绍如何将大型应用,移植到Flutter。而本文的作者——一位来自澳洲的Native iOS & Flutter的开发者,尝试这样做了,结果让他十分惊讶。到底是什么情况?一起来看文章吧!

澳大利亚有一个名为Easy Diet Diary的原生iOS应用程序。

该应用:

• 已被下载120万次;

• 用Objective-C和Swift编写,后端是Amazon AWS;

• 代码统计工具CLOC,报告该应用包含75,000行代码。

我在这家小公司工作了很长一段时间,他们的任务列表上一直有个安卓版本,但我们一直没有开发,因为:

• 支持两个代码库需要太多精力且难以管理。

• 跨平台开发的主要选择Xamarin和React Native都有重要缺陷(这是另一个故事)。

最后,我们选择进入Flutter的世界!

Flutter的速度很快,并且可以保证用户界面体验,而且一切都与原生应用没有区别(特别是有了2018年9月加入的iOS小窗体之后)。

以下是本文的主干:

• 代码行数与开发速度

• 架构

• 社区

• 性能

• 语言

• 还缺少什么?

• 结论

代码行数与开发速度

第一阶段我预估需要6个人月。但是,项目进度居然领先了!对我来说,这简直太不可思议了。

为什么?

Flutter的布局并不是像iOS那样,使用的不是Storyboard,或者像安卓那样使用XML,而是在代码中将窗体组合成窗体树,即可创建应用程序的用户界面。这对我来说听起来有点可怕,但是我做了尝试,虽然花了一些时间来习惯,但不久我就可以灵活地使用这些窗体树了。

然后,大约第一个阶段进展到第三个月的时候,发生了一件很奇怪的事情。随着我越来越熟练、越来越快地移植功能,项目中的代码行却开始迅速减少了。这很奇怪,因为我移植的业务逻辑数量非常庞大,这些逻辑在代码数量上的比例几乎是一比一。

事情的真相是,我可以通过创建类和编写函数来重用用户界面部分的代码,这比使用原生iOS更容易。通常,我可以利用几个额外的参数,简单地重构用户界面的窗体就可以重用它们。如果这样不行,我还可以简单地在现有的窗体周围再包上另一个窗体,就可以实现需要的行为了。这简直太赞了!

最终我预计代码行数将少于30,000(而原生iOS版本为75,000行)。当然,原生iOS版本包含一些虽然当时开发了最终却被取代或未被使用的代码。我估计未使用的代码占15,000行。换句话说,需要移植的代码量为60,000行。

因此,总的来说,Flutter的代码量只有原生iOS原有代码的一半!

此外,Flutter项目不包含任何Storyboard XML。Storyboard中有很多XML。原生iOS项目包含:

• 15个Storyboard;

• 47个Nib文件;

• 92个View Controllers。

我与Storyboard斗争了很多年,一直在尝试遵循最佳实践,最后感觉在Flutter中构建用户界面非常自由而且速度很快。

以前我没有意识到自己的大部分时间都用在了编写与用户界面相关的代码,还要忍受大量的Storyboard和自动布局限制。

我无数次听人说应该将用户界面布局与代码分开,我非常同意,但就我的Flutter经验而言,这一点未必是真的。而且关于用户界面分离的这种概念也不仅仅是原生iOS的最佳实践。

我记得自己在微软WPF中与XML作斗争,也见过Quora上有人问《为什么安卓使用XML来定义用户界面而不仅仅是Java代码?》

Storyboard是一种自上至下的布局方式(适用于桌面应用程序),而窗体采用自下而上的方法,在构建移动应用程序时,窗体可以极大地简化编程。我听说这种方式类似于React Native和CSS flex-boxes的布局方式。Wm Leler在Hacker Noon上发表的文章《Flutter带来了哪些创新》很好地解释了这个问题。

以下方式对于利用窗体构建用户界面很有帮助性:

• 大多数情况下,Flutter中支持状态的“热重载”功能可以在几秒钟内,将代码更改无缝地整合到正在运行的应用程序中;

• Android Studio的快捷键Alt + Enter可以插入或删除用户界面的窗体(行、列或容器)。请查看这篇文章《使用Android Studio开发Flutter应用程序的小窍门》(https://medium.com/@liewjuntung/tips-on-using-android-studio-to-develop-flutter-apps-9e42c047b7f4)。

我觉得VS Code中应该有类似的东西。这似乎微不足道,但我觉得这个快捷键十分有用。使用热重载和Alt + Enter,我可以在几分钟内做好一个画面,甚至可以在用户界面上做实验。

• 将debugPaintSizeEnabled设置为true。这会在所有用户界面的窗体周围显示鲜艳的边框。实际上这个功能用得并不如想象得多,但是当布局出现问题时该功能确实非常有用。

架构

我在选择架构时做了如下几件事:

• 看了几遍Brian Egan的这个演讲《保持简单、有状态:Flutter应用的架构》(https://www.youtube.com/watch?v=zKXz3pUkw9A&feature=youtu.be)。

• 读了几遍Eric Windmill的这篇文章《有效地使用Flutter的继承窗体》(https://ericwindmill.com/posts/inherited_widget/)。

• 阅读Flutter架构示例:http://fluttersamples.com/。

最终,我按照Eric的建议使用了一种名为Lifting State Up的架构模式,这是Redux的第一步,看起来非常诱人。然而,Redux对我来说遥不可及。由于开发时间紧迫,学习和尝试Redux似乎太令人生畏了。

一路走来,我从Stack Overflowers上的人解答的关于架构的问题中得到了许多帮助。这让我想到了社区。

社区

有关Flutter的开源社区非常多元化,并且非常乐于助人,让我看到了人类的希望(特别是在这些疯狂的时期)。

举个例子,当时我正在使用Romain Rastel编写的flutter_slidable软件包,而且我还提了一个改善建议,仅仅48小时之内他就实现了一个比我想象的更好的解决方案......类似这样的事情比比皆是。

我唯一遗憾的是,我一直忙于移植工作,与我收到的帮助相比,我给予别人的远远不够。

性能

总的来说,参加了内部测试的用户对Flutter的“活泼”非常满意。在同一台iOS设备上,同时并排运行iOS应用与Flutter应用时,并没有看到性能明显下降。

我们的应用没有很多需要大量图形的任务,但有一个功能需要从数百个JSON文件读取数据,然后对该数据进行一系列浮点计算,在该功能中Flutter的应用明显更快。

我没有花时间去研究导致差异的究竟是是读取文件的功能、还是JSON解析或者是日期处理等等,因此我无法做出类别上的判断,但我感觉这无疑是Flutter桂冠上的一颗明珠。

很期待看到其他人能给出怎样的性能测试数据。

语言

Flutter使用Dart,这种语言已经在Google之外萎靡不振,直到最近才随着Flutter再次兴起。

然而,这门语言很成熟且易于学习。幸运的是,我在加入Dart队伍时,拥有更强大的类型功能的Dart 2.0刚刚出现,所以无需再在代码中不断地敲“new”关键字了。

Dart可能没有Swift和Kotlin所拥有的Null和非Null类型,但我很喜欢它的简单性。 例如:

• 以下划线开头的函数为私有;

• 自动格式化意味着不必再头疼我的习惯问题——我喜欢在末尾加上逗号将参数分行;

• 包管理很简单。

还有很多很多。我喜欢这些功能,也许其他人可能不喜欢。对我而言,最重要的是我可以更快地(用奇怪但很愉悦的方式)实现功能。

还缺少什么?

没有太多缺少的东西。在原生iOS应用中:

• 我在XCode中使用了很多Targets,并结合一堆#define创建bundle ID不同的各种版本的应用。我不知道在Flutter中怎么处理这个问题;

• 我在iOS中使用了一个很好的第三方日志框架,叫做CocoaLumberjack。还没找到能代替它的东西;

• 我使用UIKit框架中的WKWebView来加载并渲染本地的HTML文件(如使用条款、隐私政策等)。我在Flutter中没找到正确的包来实现这个功能。最后只能使用一个包HTML2MD将HTML转换成Markdown再使用另一个包flutter_markdown来渲染;

• 我使用AVFoundation框架,在单一的全屏视图中实现条码扫描、QR二维码扫描和拍照。在Flutter中我还不能如此细致地进行控制,虽然它的Camera包很适合拍照,另一个由facundomedica编写的包fast_qr_reader_view很适合扫描条码。在安卓设备上,这个包与Firebase的ML Kit配合从Camera包中获取实时图像。

结论

读到这里,你肯定不会惊讶为什么我如此赞美Flutter。到目前为止:

• Flutter的用户界面几乎与原生安卓和原生iOS的用户界面没有区别;

• 得益于Flutter用户界面的构建方式,利用Flutter制作新功能比原生代码更快;

• 测试没有收到有关性能劣化的报告;

• iOS版和安卓版之间的代码共享目前达到了90%以上。我还没有集成苹果的HealthKit或Google Fit,但我觉得共享率应该不会下降太多。

尽管Flutter还不成熟(2018年5月才发布正式版),但对于我来说它已经足够强壮了。

我遇到的唯一问题就是Dart同步读取目录的函数List Sync在最近的一次发布中出现了崩溃。我将它加到了Flutter在Github上的代码库中,然后改用异步版本。

原文:https://medium.com/flutter-community/porting-a-75-000-line-native-ios-app-to-flutter-57c6571c57b4

作者:Gary Hunter,Native iOS & Flutter的开发者。

译者:弯月,责编:胡巍巍

推荐阅读:

  • BAT 厮杀的小程序与手机厂商叫板的快应用,对开发者意味着什么?

  • 前端工程师掌握这18招,就能在浏览器里玩转深度学习

  • 比特币泡沫之后,加密货币投资者学到的教训

  • 有时间BB,不如想想怎么让别人闭嘴吧

  • 来呀!AI喊你斗地主——首个搞定斗地主的深度神经网络

  • 程序员的江湖 务必掌握这些黑话!

  • 富人越富,穷人越穷,我为什么反对PoS

将 75000 行原生 iOS 应用程序移植到 Flutter 后,结果太惊讶!相关推荐

  1. 程序员踩坑之旅:将 75000 行 iOS 原生代码迁移到 Flutter!

    人们普遍认为,如果想构建一个良好的移动应用,则必须建立iOS和Android两个版本.与此同时大多数企业想要的是:只实现一次业务逻辑,并快速打包成具有原生体验感的用户界面. 作者 | Gary Hun ...

  2. 用Adobe Flash Professional CS6创建一个iOS应用程序

    引用:http://news.9ria.com/2013/0104/25780.html 平板电脑和智能手机的迅速增长意味着将会有比以往任何时候都多的人使用移动设备来浏览在线内容.其结果就是,Web设 ...

  3. 25个增强iOS应用程序性能的提示和技巧 — 中级篇

    本文由破船译自:raywenderlich 转载请注明出处:BeyondVincent的博客 _____________ 在开发iOS应用程序时.让程序具有良好的性能是非常关键的.这也是用户所期望的. ...

  4. 【转】将 Linux 应用程序移植到 64 位系统上

    原文网址:http://www.ibm.com/developerworks/cn/linux/l-port64.html 随着 64 位体系结构的普及,针对 64 位系统准备好您的 Linux® 软 ...

  5. jquery程序 windows移植到linux显示不了,windows程序移植linux

    1,路径名统一用正斜杠"/".(windows下正反斜杠都识别,linux只认正斜杠.) 2,统一使用UTF-8格式编码. vim中无法保存汉字时,可输入下列命令: :set fi ...

  6. mpvue 微信小程序api_第三方框架与原生微信小程序开发框架性能之比较 | Q荐读...

    作者 | 崔红保编辑 | 王莹 自 2017年1月9日微信小程序诞生以来,历经 2 年多的迭代升级,已有数百万小程序上线,成为继 Web.iOS.Android 之后,第四大主流开发技术. 与之相随, ...

  7. Qt for ios 设置程序显示名称

    前言 Qt 开发 IOS 程序,编译出来软件的默认名称就是 Qt 的工程名,包括 Qt 开发 Android 也是一样,修改 android 的程序显示名称需要在 AndroidManifest文件中 ...

  8. [转]25个增强iOS应用程序性能的提示和技巧

    在开发iOS应用程序时,让程序具有良好的性能是非常关键的.这也是用户所期望的,如果你的程序运行迟钝或缓慢,会招致用户的差评.然而由于iOS设备的局限性,有时候要想获得良好的性能,是很困难的.在开发过程 ...

  9. rn项目 假如cocoapods_React Native 如何集成到原生IOS项目中?

    想了很久,要先介绍各种组件的实际应用好,还是先介绍怎么把React Native集成到原生项目好. 因为想起,一旦开始写各种组件的应用,就会花很长很长的篇幅,会把这个挺重要的内容抛到好远,而集成到原生 ...

最新文章

  1. 社团发现算法-BGLL算法(附代码实现)
  2. IBM Cloud Speech to Text 语音识别
  3. 【学习笔记】SAP Fiori相关概念介绍
  4. Jmeter之CSS选择器/JQuery选择器关联
  5. 数据集如何影响作物病害识别的有效性
  6. 如何通过看书来学习技术
  7. CSS:结合clip-path实现目录的隐藏显示以及提示框的隐藏显示
  8. 待续--著名软件公司笔试算法题:122345排列组合
  9. 视频格式转换工具,用到ws.schild.jave,之前是用的it.sauronsoftware.jave,作者已经不维护了
  10. 网页在线客服代码-侧边悬浮在线客服/QQ/微信/电话代码
  11. 清理git本地帐户信息
  12. 大学物理笔记——第二章质点动力学
  13. 关于累加偶数奇数的c语言程序,c语言 在1-100之间,求所有奇数和偶数的个数和所有奇数和偶数的和(写到一个里面)...
  14. 用SAS如何读取数据
  15. 【BSC】使用Python玩转PancakeSwap(入门篇)
  16. 有一种爱 不能称之为爱情
  17. Word2013制作中国的传统福字在屋门上贴的福字(福倒了)
  18. 51单片机——蜂鸣器的使用
  19. mac系统设置alias
  20. 计算机主机无法开机故障原因,惠普电脑开不了机怎么办 惠普电脑开不了机是什么原因 惠普电脑开机常见问题...

热门文章

  1. 在gcp终端中使用ssh连接到本地机器
  2. leetcode python3 简单题88. Merge Sorted Array
  3. popoupwindow 点击背景消失_两种去除背景音乐保留原声的高效方法
  4. Golang的time包的应用
  5. Flutter进阶—实现动画效果(五)
  6. Flutter进阶—质感设计之标签栏
  7. 中国塑料食品和饮料包装行业市场供需与战略研究报告
  8. 《Python游戏趣味编程》 第7章 飞机大战
  9. 近7成开发者无开源收入、最想操作系统开源、Java最受欢迎 | 揭晓中国开源开发者现状...
  10. 微软若“无故”解雇暴雪 CEO,将付 1500 万美元“分手费”