Flutter最近好像🔥了,讲真,自己试一下才知道,页面体验是真的好,感觉Flutter就是移动端的未来...
创建全新的Flutter项目简单,在已有项目上进行集成可能得费点周章,但是,有我的这篇亲身实践的教程,保你少走弯路,一步直达
关于配置Flutter环境,还是得烦劳各位自行配置。本文的实践前提是
➜ qding_flutter git:(dev_wuhaiwei) flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel master, v1.2.3-pre.31, on Mac OS X 10.13.6 17G3025, locale zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.2)
[✓] VS Code (version 1.30.2)
[✓] Connected device (1 available)
• No issues found!
No issues found!
官方的集成方案
ok,废话说了一通,上开胃甜点,官方有提供现成的集成方案,
Add Flutter to existing apps
官方教程倒也不麻烦,建议有兴趣的还是跟着官方教程走一遍,去理解一下。说一下这个集成方案的缺点:
- 步骤略繁琐
- 对原工程侵入较大,项目里面每个人都得安装Flutter环境,影响其它开发同事
-
集成后Xcode编译速度贼慢,不更改任何代码,每次command + R都需要2-4分钟,这个真心不能忍.
如图:
当然,如果你是一个人开发并且不介意以上缺点,官方的集成方案非常适合你
鉴于一般情况下大家都不是一个人在战斗,官方的集成方案就目前来看很明显的拖累整个team的开发效率,跨平台应当提高开发效率,这与初衷不符啊。寻寻觅觅,凄凄惨惨戚戚。关于Flutter的编译原理咱暂时也没有跟多的了解,咱也不吹,只是知道Flutter sdk的最终编译结果是App.framework、Flutter.framework.前者是开发的Dart代码,后者是Flutter解析引擎。这就相当于有枪有炮,干就完了。
集成Flutter编译产物
上硬菜..
目前我这边是这样处理的,单独创建一个Flutter项目: qdapp-flutter
安卓、iOS的flutter代码都在这个里面。在 qdapp-flutter目录下进行编译:
1、 debug模式: 生成debug包 App.framework、Flutter.framework,debug支持热重载
➜ qding_flutter git:(dev_wuhaiwei) flutter build ios --debug
2、release模式: 生成对应的release包,不支持热重载,并且xcode打ipa包时集成的flutter包一定要是 release包
➜ qding_flutter git:(dev_wuhaiwei) flutter build ios --release
大家可以每次手动将 App.framework、Flutter.framework拖入iOS原生项目中,此非我所欲也。
让 qdapp-flutter支持cocoapods岂不更好,说干就干,由于我们公司并没有创建私有repo的传统,就沿用了旧习,只是单纯的让 qdapp-flutter支持cocoapods进行更新。在qdapp-flutter根目录下创建了QDFlutterSDK.podspec文件,文件内容如下:
Pod::Spec.new do |s|
s.name = "QDFlutterSDK"
s.version = "1.0.5"
s.summary = "app Flutter模块儿组件"
s.homepage = "此处放git/gitlab/等地址即可"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "wuhaiwei" => "wuhaiwei0809@163.com" }
s.platform = :ios, "8.0"
s.ios.deployment_target = "8.0"
#我认为不创建私有repo的情况下,此处定义source没有意义,可忽略
s.source = { :git => "项目在git上的地址.git", :tag => s.version }
# s.source_files = "qding_flutter/.ios/Flutter/*.rb"
#通过cocoapods只安装两个framework
s.vendored_frameworks = ['qding_flutter/.ios/Flutter/App.framework',
'qding_flutter/.ios/Flutter/engine/Flutter.framework']
end
同时在根目录下创建了 LICENSE文件,LICENSE文件内容如下:
Copyright (c) 2018-2019 QDFlutterSDK Software Foundation (项目地址)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
至此,qdapp-flutter项目应该已经支持cocoapods进行安装,如有异常
还请大家自行搜索
接下来就是在iOS原生项目中修改Podfile文件:
#QDFlutterSDK 组件
# pod 'QDFlutterSDK', :git => "qdapp-flutter 项目私有地址", :tag =>'1.0.0'
# 调试启用
pod 'QDFlutterSDK', :git => "qdapp-flutter 项目私有地址.git", :branch => 'dev_wuhaiwei'
然后pod install,顺利的话应该会看到两个framework已经安装到iOS原生项目中
接下来就是引用库文件了,如何引用还请参考官方文档,很详细。
如果顺利Flutter模块已经可以正常打开,而且运行Xcode与集成Flutter之前没有任何区别,对于非Flutter开发来说,这个集成过程是无感知的!
这,就是它对我的吸引
值得注意的是,qdapp-flutter工程有更改之后,需要进行重新编译,重新生成对应的.framework,并在iOS原生工程进行更新。似有不妥,有改动就这么麻烦还如何debug开发?
关于如何进行debug开发
常理来说,集成了.framework之后就没办法进行debug开发,更别提热重载
方式一
1、先在Xcode中连上iPhone,command+R,打开flutter页面
2、打开Android Studio,不能运行,在终端中执行
➜ qding_flutter git:(dev_wuhaiwei) flutter attach
如图:
有些情况下方式一无效,所以方式二来了。
方式二
1、先在Xcode中连上iPhone,command+R,打开flutter页面
此时在Xcode的控制台里面会打印
2019-04-02 17:44:33.596805+0800 qding[4349:1205008] flutter: Observatory listening on http://127.0.0.1:64108/
记录控制台中的端口号,例如我的是:64108
2、打开Android Studio,不能运行,在终端中执行
➜ qding_flutter git:(dev_wuhaiwei) ✗ flutter attach --debug-port=64108
很明显,终于连上了
根据提示,更改dart代码,输入“R”,愉快的进行热重载开发吧
关于debug过程中的一些异常
1、昨天热重载的好好的,睡了一觉到公司热重载嗝屁了,报错:
Error connecting to the service protocol: HttpException: , uri = http://127.0.0.1:1024/ws
stackover flow上有跟我一样的问题,睡了一觉,flutter就挂了,对我来说有用的解决方案在这里:
https://github.com/flutter/flutter/issues/25112#issuecomment-455410536
关闭手机wifi,用4G网络就好了。据说是Flutter 热重载的bug。
2、今天切换了一下flutter分支,从master切换到stable分支之后报错如下:
➜ qding_flutter git:(dev_wuhaiwei) ✗ flutter build ios --debug
Building com.qianding.flutter for device (ios)...
Automatically signing iOS for device deployment using specified
development team in Xcode project: 6232V88552
├─Assembling Flutter resources... 1.6s └─Compiling, linking and signing... 0.6s Xcode build done. 4.3s Failed to build iOS app Error output from Xcode build:
↳
** BUILD FAILED **
Xcode's output:
↳
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION
Debug ===
fatal error: lipo: -extract arm64 specified but fat file:
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/D
ebug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter
does not contain that architecture
Failed to extract arm64 for
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/D
ebug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter.
Running lipo -info:
Architectures in the fat file:
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/D
ebug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter
are: armv7
Encountered error while building for device.
上面的信息表明,fat library里面需要包含 arm64架构的包,目前没有,里面只是armv7的包,验证如下:
➜ qding_flutter git:(dev_wuhaiwei) ✗ lipo -info /Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter
Architectures in the fat file: /Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter are: armv7
很明显是Runner里面的设置问题,它要arm64,给她就是喽。修改设置如下:
重新编译debug包
➜ qding_flutter git:(dev_wuhaiwei) ✗ flutter build ios --debug
Building com.qianding.flutter for device (ios)...
Automatically signing iOS for device deployment using specified
development team in Xcode project: 6232V88552
Running Xcode build... ├─Assembling Flutter resources... 1.5s
└─Compiling, linking and signing... 3.3s
Xcode build done. 6.3s
Built
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/iphon
eos/Runner.app.
编译通过。
检测如下:
➜ qding_flutter git:(dev_wuhaiwei) ✗ lipo -info /Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter
Architectures in the fat file: /Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Frameworks/Flutter.framework/Flutter are: x86_64 armv7 arm64
已经包含了arm64包
3、偶尔编译的时候报错:
➜ qding_flutter git:(dev_wuhaiwei) ✗ flutter build ios --debug
Building com.qding.flutter for device (ios)...
Automatically signing iOS for device deployment using specified development team in Xcode project:
6232V88552
├─Assembling Flutter resources... 1.5s └─Compiling, linking and signing... 1.6s Xcode build done. 5.2s
Failed to build iOS app
Error output from Xcode build:
↳
** BUILD FAILED **
Xcode's output:
↳
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Debug ===
Non-fat binary
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Framework
s/App.framework/App is not armv7. Running lipo -info:
Non-fat file:
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos/Runner.app/Framework
s/App.framework/App is architecture: arm64
Command /bin/sh failed with exit code 1
意思就是说在目录 下面目录中的App.framework缺少armv7的二进制包
/Users/wuhaiwei/Desktop/qdapp-flutter/qding_flutter/build/ios/Debug-iphoneos
重新编译不行,无法覆盖,我删除了上面目录下的Runner.app文件,重新编译,搞定。
4、关于如何打断点
我这边尝试在android studio里面打断点、print(), debugPrint(),统统都不管用, logcat里面根本找不到iOS的模拟器,然而又需要iOS的模拟器或者真机进行交互联调,很苦恼。一个安卓同事提醒:你在你们xcode里面看看有没有打印,果然打印数据出现在了xcode里面,纳尼??
接下来一起愉快的写Bug吧