Flutter与Xcode那些事
Hi, 各位看官, 里边请! 😁
最近在搞Flutter, 来跟各位随便唠唠! 今天我们不说语法, 也不说 widget 哈! 有兴趣的小伙伴可以点击链接去查看Flutter相关内容!
今天跟看官们说说, Flutter 与 iOS交互的那些事! 由于我的本没有安装 Android Studio, 则用VS Code来说, 本期主要围绕着 Xcode 来讲!
关于安卓其结构都一样, 后期会推出!
在iOS 原有的项目中集成Flutter
原有的项目我就不做展示了哈, 我用一个Demo 来演示! 其效果是一样
-
首先打开终端, 输入 flutter create --template module my_flutter, 创建 module, 命名为my_flutter
然后打开module, ( Tip: 在集成进 Xcode之前, model 最好先运行起来)
![](https://img.haomeiwen.com/i4053175/cb02dfa6242c82dd.png)
- 我相信身为iOS开发者对CocoaPods都不陌生吧, 本期将通过CocoaPods管理, 把刚刚创建的 Flutter module 集成到项目中
1.打开 Podfile 文件, 在其中添加 module 本地路径:
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
# 添加模块所在路径
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'useFlutter' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# 安装Flutter模块
install_all_flutter_pods(flutter_application_path)
end
- 添加完成后,保存退出! 然后 pod install
3.打开Xcode项目, 在AppDelegate中创建引擎
class AppDelegate: UIResponder, UIApplicationDelegate {
// 1. 创建 flutterEngine name: 引擎名称
lazy var flutterEngine = FlutterEngine(name: "Evan_Engine")
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 2.启动引擎
flutterEngine.run()
return true
}
}
4.来到 ViewController中来使用 Flutter module
// 该函数为Button点击事件
@IBAction func flutterPush(_ sender: Any) {
// 3. 创建FlutterViewController对象(需要先获取flutterEngine)
let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine;
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil);
flutterViewController.modalPresentationStyle = .fullScreen
self.present(flutterViewController, animated: true, completion: nil)
}
我们也可以省略预先创建的 FlutterEngine :
但不推荐这样来做,因为在第一针图像渲染完成之前,可能会出现明显的延迟。
@IBAction func flutterPush(_ sender: Any) {
let flutterViewController = FlutterViewController(project: nil, nibName: nil, bundle: nil)
present(flutterViewController, animated: true, completion: nil)
}
-
把项目运行起来, 点击Button, 来看看效果
哈哈, 是不是感觉好简单!
Tip: 不要把 widget 作为 view 来与原生的同一个页面上混用, 可能会有不可预知行为! 切记切记
-
虽说是用Xcode在运行, 但我们还是可以继续来使用 Hot Reload
-
打开 module, 在终端执行 flutter attach, 链接成功后, 如下图
2.此时我们就可以去修改代码, 将 Text 字体颜色改为red, 修改完后先保存, 然后在VS Code 终端中输入 r, 则执行了Hot reload, 此时屏幕也随之发生了改变, 大功告成! 😁
![](https://img.haomeiwen.com/i4053175/46418906b0c6b72b.png)
注意: 目前一些场景依然是有限制的:
- 运行多个Flutter实例,或在屏幕局部上运行Flutter可能会导致不可以预测的行为;
- 在后台模式使用Flutter的能力还在开发中(目前不支持);
- 将Flutter库打包到另一个可共享的库或将多个Flutter库打包到同一个应用中,都不支持;
- 添加到应用在Android平台的实现基于 FlutterPlugin 的 API,一些不支持FlutterPlugin 的插件可能会有不可预知的行为。
Flutter 与 iOS 交互
- 打开Flutter 项目, 创建 StatefulWidget,
- 创建通信对象 MethodChannel
- 调用原生的函数 getOriginalContent
class MyInteractionBody extends StatefulWidget {
@override
_MyInteractionBodyState createState() => _MyInteractionBodyState();
}
class _MyInteractionBodyState extends State<MyInteractionBody> {
// 1.创建通信对象 MethodChannel
static const platForm = MethodChannel('Evan_channel');
var _content = '文案';
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_content),
SizedBox(height: 10,),
TextButton(
child: Text('调用原生函数'),
onPressed: getContent)
],
),
);
}
void getContent() async {
// 2. 调用原生的函数 getOriginalContent, 等待回调
final result = await platForm.invokeMethod('getOriginalContent');
setState(() {
_content = result;
});
}
}
- 使用Xcode打开Flutter 中 ios文件中的项目, 在需要处添加以下代码
// 1.获取 FlutterViewController
if let controller: FlutterViewController = window.rootViewController as? FlutterViewController {
// 2. FlutterMethodChannel
let channel = FlutterMethodChannel(name: "Evan_channel", binaryMessenger: controller.binaryMessenger)
// 3.监听 channel 调用方法
channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
// 函数名称
if call.method == "getOriginalContent" {
// 如果没有获取到,那么返回给Flutter端一个异常
// result(FlutterError(code: "0", message: "错误", details: nil))
// 通过result将结果回调给Flutter端
result(self.getOriginalContent())
} else {
// 未找到
result(FlutterMethodNotImplemented)
}
}
}
func getOriginalContent() -> String { "已经与原生成功交互" }
到此交互就可以使用了!
好了, Flutter 与 Xcode 交互这点事, 大体上也都跟各位看官唠完了, 以上只是一些基本简单用法, 更多的技能还需要用各位去探索, 研究哦!