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

简介:   很少有文章,介绍如何将大型应用,移植到Flutter。而本文的作者——一位来自澳洲的Native iOS & Flutter的开发者,尝试这样做了,结果让他十分惊讶。到底是什么情况?一起来看文章吧!  将 75000 行原生 iOS 应用程序移植到 Flutter 后,结果太惊讶!  澳大利亚有一个名为Easy Diet Diary的原生iOS应用程序。  该应用:

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

  将 75000 行原生 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可以插入或删除用户界面的窗体(行、列或容器)。

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

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

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

  看了几遍Brian Egan的这个演讲《保持简单、有状态:Flutter应用的架构》

  读了几遍Eric Windmill的这篇文章《有效地使用Flutter的继承窗体》

  最终,我按照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上的代码库中,然后改用异步版本。

目录
相关文章
|
9天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
46 4
|
2月前
|
设计模式 安全 Swift
探索iOS开发:打造你的第一个天气应用
【9月更文挑战第36天】在这篇文章中,我们将一起踏上iOS开发的旅程,从零开始构建一个简单的天气应用。文章将通过通俗易懂的语言,引导你理解iOS开发的基本概念,掌握Swift语言的核心语法,并逐步实现一个具有实际功能的天气应用。我们将遵循“学中做,做中学”的原则,让理论知识和实践操作紧密结合,确保学习过程既高效又有趣。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你打开一扇通往iOS开发世界的大门。
|
23天前
|
存储 调度 数据安全/隐私保护
鸿蒙Flutter实战:13-鸿蒙应用打包上架流程
鸿蒙应用打包上架流程包括创建应用、打包签名和上传应用。首先,在AppGallery Connect中创建项目、APP ID和元服务。接着,使用Deveco进行手动签名,生成.p12和.csr文件,并在AppGallery Connect中上传CSR文件获取证书。最后,配置签名并打包生成.app文件,上传至应用市场。常见问题包括检查签名配置文件是否正确。参考资料:[应用/服务签名](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-signing-V5)。
53 3
鸿蒙Flutter实战:13-鸿蒙应用打包上架流程
|
18天前
|
JSON 前端开发 API
探索iOS开发之旅:打造你的第一个天气应用
【10月更文挑战第36天】在这篇文章中,我们将踏上一段激动人心的旅程,一起构建属于我们自己的iOS天气应用。通过这个实战项目,你将学习到如何从零开始搭建一个iOS应用,掌握基本的用户界面设计、网络请求处理以及数据解析等核心技能。无论你是编程新手还是希望扩展你的iOS开发技能,这个项目都将为你提供宝贵的实践经验。准备好了吗?让我们开始吧!
|
27天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
49 1
|
2月前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
2月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
52 5
|
2月前
|
移动开发 前端开发 Swift
iOS 最好的应用程序开发编程语言竟然是这7种
iOS 最好的应用程序开发编程语言竟然是这7种
96 8
|
27天前
|
存储 Dart
Flutter&鸿蒙next 实现一个计算器应用
本文介绍了如何使用 Flutter 创建一个简单的计算器应用,包括基本的加减乘除运算。文章详细讲解了界面布局、计算逻辑和状态管理的实现步骤,通过具体的代码示例展示了如何构建计算器界面、处理用户输入和显示计算结果。
74 0
|
27天前
|
传感器 开发框架 物联网
鸿蒙next选择 Flutter 开发跨平台应用的原因
鸿蒙(HarmonyOS)是华为推出的一款旨在实现多设备无缝连接的操作系统。为了实现这一目标,鸿蒙选择了 Flutter 作为主要的跨平台应用开发框架。Flutter 的跨平台能力、高性能、丰富的生态支持和与鸿蒙系统的良好兼容性,使其成为理想的选择。通过 Flutter,开发者可以高效地构建和部署多平台应用,推动鸿蒙生态的快速发展。
176 0