赞
踩
Flutter
直接说一下flutter的核心代码.
创建对象
// 创建与iOS沟通的渠道
// 该方法用于flutter主动发消息给iOS监听的
var channel = const MethodChannel('com.pages.flutter');
调iOS
channel.invokeMethod('red_view_controller', null);
iOS
iOS这边的核心代码
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
MethodChannelDemo(messenger: controller.binaryMessenger)
import Flutter import UIKit public class MethodChannelDemo { var count = 0 var channel:FlutterMethodChannel init(messenger: FlutterBinaryMessenger) { //与flutter建立通道 "com.pages.flutter"的通道命名要与flutter一致 channel = FlutterMethodChannel(name: "com.pages.flutter", binaryMessenger: messenger) //接收来自flutter传过来的值。 'sendData'的方法命名与flutter要一致 channel.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in if (call.method == "red_view_controller") {//唤起自定义原生控制器 let viewController = RedViewController() if let rootViewController = UIApplication.shared.keyWindow?.rootViewController { rootViewController.present(viewController, animated: true, completion: nil) } } } } }
RedViewController就不写了,里面两个Label用于显示的
Flutter
// 创建与iOS沟通的渠道
// 该方法用于flutter主动发消息给iOS监听的
var channel = const MethodChannel('com.pages.flutter');
channel.invokeMethod('red_view_controller', {'name': 'laomeng', 'age': '18'});
iOS
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
MethodChannelDemo(messenger: controller.binaryMessenger)
import Flutter import UIKit public class MethodChannelDemo { var count = 0 var channel:FlutterMethodChannel init(messenger: FlutterBinaryMessenger) { //与flutter建立通道 "com.pages.flutter"的通道命名要与flutter一致 channel = FlutterMethodChannel(name: "com.pages.flutter", binaryMessenger: messenger) //接收来自flutter传过来的值。 'sendData'的方法命名与flutter要一致 channel.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in if (call.method == "red_view_controller") {//唤起自定义原生控制器 var nameParams = String() var ageParams = String() if let dict = call.arguments as? Dictionary<String, Any> {//把接收到的值转换成字典 nameParams = dict["name"] as? String ?? "" //通过字典的key获取对应的value ageParams = dict["age"] as? String ?? "" //通过字典的key获取对应的value } let viewController = RedViewController() viewController.name = nameParams viewController.age = ageParams if let rootViewController = UIApplication.shared.keyWindow?.rootViewController { rootViewController.present(viewController, animated: true, completion: nil) } } } } }
RedViewController就不写了,里面两个Label用于显示的
Flutter
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class Category extends StatefulWidget { const Category({Key? key}) : super(key: key); @override State<Category> createState() => _Category(); } class _Category extends State<Category> { // 创建与iOS沟通的渠道 // 该方法用于flutter主动发消息给iOS监听的 var channel = const MethodChannel('com.pages.flutter'); // 原生回调的数据 var _callbackData; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextButton( child: const Text('调起原生的控制器,有参数,无返回值'), onPressed: () async { var result = await channel.invokeMethod('red_view_controller', {'name': 'laomeng', 'age': '18'}); var name = result['name']; var age = result['age']; setState(() { print('返回的名称: $name result $result'); _callbackData = 'name: $name age: $age'; }); }, ), Text('原生收到相应并返回数据:$_callbackData'), ], ), ), ); } }
iOS
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
MethodChannelDemo(messenger: controller.binaryMessenger)
import Flutter import UIKit public class MethodChannelDemo { var count = 0 var channel:FlutterMethodChannel init(messenger: FlutterBinaryMessenger) { //与flutter建立通道 "com.pages.flutter"的通道命名要与flutter一致 channel = FlutterMethodChannel(name: "com.pages.flutter", binaryMessenger: messenger) //接收来自flutter传过来的值。 'sendData'的方法命名与flutter要一致 channel.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in if (call.method == "red_view_controller") {//唤起自定义原生控制器 var nameParams = String() var ageParams = String() if let dict = call.arguments as? Dictionary<String, Any> {//把接收到的值转换成字典 nameParams = dict["name"] as? String ?? "" //通过字典的key获取对应的value ageParams = dict["age"] as? String ?? "" //通过字典的key获取对应的value result(["name":"return \(nameParams)","age":"return \(ageParams)"]) } let viewController = RedViewController() viewController.name = nameParams viewController.age = ageParams if let rootViewController = UIApplication.shared.keyWindow?.rootViewController { rootViewController.present(viewController, animated: true, completion: nil) } } } } }
RedViewController就不写了,里面两个Label用于显示的
iOS
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let _ = MethodChannelDemo(messenger: controller.binaryMessenger)
import Flutter import UIKit public class MethodChannelDemo { var channel:FlutterMethodChannel init(messenger: FlutterBinaryMessenger) { //与flutter建立通道 "com.flutter.guide.MethodChannel"的通道命名要与flutter一致 channel = FlutterMethodChannel(name: "com.flutter.guide.MethodChannel", binaryMessenger: messenger) //接收来自flutter传过来的值。 'sendData'的方法命名与flutter要一致 channel.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in//flutter call ios if (call.method == "dumpViewController") { let viewController = ViewController() if let rootViewController = UIApplication.shared.keyWindow?.rootViewController { rootViewController.present(viewController, animated: true, completion: nil) } } } } }
iOS(Swift)控制器调用flutter的核心代码
import UIKit import Flutter class ViewController: UIViewController { lazy private var btnOne: UIButton = { let button = UIButton() button.backgroundColor = .blue button.addTarget(self, action: #selector(buttonOneClick), for: .touchUpInside) return button }() lazy private var btnTwo: UIButton = { let button = UIButton() button.backgroundColor = .blue button.addTarget(self, action: #selector(buttonTwoClick), for: .touchUpInside) return button }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(btnOne) view.addSubview(btnTwo) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() btnOne.frame = CGRectMake(view.bounds.size.width*0.5 - 25, view.bounds.size.height*0.5 - 100, 50, 50) btnTwo.frame = CGRectMake(view.bounds.size.width*0.5 - 25, view.bounds.size.height*0.5 + 100, 50, 50) } //ios call flutter, call success not return value @objc func buttonOneClick() { guard let controller = UIApplication.shared.keyWindow?.rootViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel(name: "com.flutter.guide.MethodChannel", binaryMessenger: controller.binaryMessenger) let args = ["name":"方法1"] channel.invokeMethod("funcOne", arguments:args) dismiss(animated: true) } //ios call flutter, call success return value @objc func buttonTwoClick() { guard let controller = UIApplication.shared.keyWindow?.rootViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel(name: "com.flutter.guide.MethodChannel", binaryMessenger: controller.binaryMessenger) let args = ["name":"方法2"] channel.invokeMethod("funcTwo", arguments:args) { (result) in if let resultString = result as? String { print("ios: \(resultString)") } } dismiss(animated: true) } }
Flutter
核心代码
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { // 创建与iOS沟通的渠道 var channel = const MethodChannel('com.flutter.guide.MethodChannel'); // 原生返回给我们的数据 var _nativeData; @override void initState() { // TODO: implement initState super.initState(); channel.setMethodCallHandler(_handleMethod); //该方法用于接收ios传过来的值(该方法时时刻刻的在监听获取iOS传递过来的值) channel.setMethodCallHandler((call) { setState(() { _nativeData = call.arguments['name']; }); // 返回一个非空的Future<void> //return Future<void>.value();//回调空值 return Future.value('flutter接收到ios的值之后,回调当前字符串给iOS'); }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextButton( child: const Text('弹出控制器'), onPressed: () async { channel.invokeMethod('dumpViewController', null); }, ), Text('原生主动发送数据给Flutter接收:$_nativeData') ], ), ), ); } Future<dynamic> _handleMethod(MethodCall call) async { switch (call.method) { case 'funcOne': setState(() { _nativeData = call.arguments['name']; }); return Future<void>.value();//回调空值 //break; case 'funcTwo': setState(() { _nativeData = call.arguments['name']; }); // 返回一个非空的Future<void> return Future.value('flutter接收到ios的值之后,回调当前字符串给iOS'); //break; // 添加其他方法的处理逻辑 default: throw MissingPluginException(); } } }
下面的方法是使用监听的方法,iOS那边的代码是没有问题的,但是flutter那边稍微是有点问题,iOS调用flutter已经把值传递过去了,已经打印出来收到了,但是调用setState没有更新UI,不知道什么原因
Flutter
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class Category extends StatefulWidget { const Category({Key? key}) : super(key: key); @override State<Category> createState() => _Category(); } class _Category extends State<Category> { // 创建与iOS沟通的渠道 // 该方法用于flutter主动发消息给iOS监听的 var channel = const MethodChannel('com.pages.flutter'); //flutter 接收swift 信息的通道(实时监听) //该方法用于 iOS主动发信息给flutter进行监听的 static const EventChannel eventChannel = EventChannel('com.pages.flutter');//App/Event/Channel和iOS的一致 // ios主动发消息给flutter接收的值 var _nativeData; // 错误处理 void _onError(dynamic) {} // 数据接收 void _onEvent(dynamic value) { print('iOS data + $value'); setState(() { // _nativeData = value.toString(); // print('setState + $_nativeData'); _nativeData = value["hello123"]; print('setState + $_nativeData'); }); } @override void initState() { // TODO: implement initState super.initState(); //开始监听,swfit 发来的的消息 eventChannel.receiveBroadcastStream("init").listen((dynamic value){ setState(() { _nativeData = value["hello123"]; print('setState + $_nativeData'); }); }, onError: _onError); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextButton( child: const Text('11111'), onPressed: () async { }, ), TextButton( child: const Text('调起原生的控制器:view_controller'), onPressed: () async { channel.invokeMethod('run_viewController', null); }, ), // Text('原生返回数据:$_callbackData'), // Text('原生返回数据:$_data'), Builder( builder: (BuildContext context) { if (_nativeData != null) { return Text('原生主动发送数据给Flutter接收:$_nativeData'); } else { return Text('等待数据...'); } }, ), ], ), ), ); } }
iOS
控制器的核心代码
import UIKit import Flutter class ViewController: UIViewController, FlutterStreamHandler { var channel:FlutterEventChannel?//频道通道 var eventSink:FlutterEventSink?//事件通道(用于将事件发送给Flutter) var flutterViewController:FlutterViewController? = nil//用于在iOS应用程序中显示Flutter内容。 //创建了一个延迟加载的FlutterEngine实例,名称为"my flutter engine",FlutterEngine负责运行一个Flutter应用程序 lazy var flutterEngine:FlutterEngine = FlutterEngine(name: "my flutter engine") lazy private var button: UIButton = { let button = UIButton() button.backgroundColor = .blue button.addTarget(self, action: #selector(buttonClick), for: .touchUpInside) return button }() override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(button) // 初始化Flutter引擎(启动flutter程序) flutterEngine.run() flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil) //初始化事件通道 channel = FlutterEventChannel(name: "com.pages.flutter", binaryMessenger: flutterViewController as! FlutterBinaryMessenger) channel?.setStreamHandler(self) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() button.frame = CGRectMake(view.bounds.size.width*0.5 - 25, view.bounds.size.height*0.5 - 25, 50, 50) } @objc func buttonClick() { //获取flutter那边的通道 let method = FlutterMethodChannel(name: "com.pages.flutter", binaryMessenger: flutterViewController as! FlutterBinaryMessenger) method.setMethodCallHandler { (callBack:FlutterMethodCall, result:FlutterResult) -> Void in //获取flutter 返回的信息 print(callBack.method,callBack.arguments ?? "") if callBack.method == "method_native_result_callback" {//调用方法 // 向Flutter发送响应消息 result("flutter: hello")//回调信息过去 } } //swift 主动发送信息给flutter let dic:[String:String] = ["hello123":"flutter456"]; self.eventSink?(dic) //这里如果创建一个新的flutter页面出来,返回的值显示上有更新,不过UI界面有问题 // self.present(flutterViewController!, animated: true, completion: nil) //这里返回有结果收到了,但是UI显示label没有更新显示,UI界面没有问题 dismiss(animated: true) } // MARK: - FlutterStreamHandler 协议方法 //ios 主动给flutter 发送消息回调方法 //当Flutter客户端开始监听事件时,onListen方法会被调用,它提供了一个事件sink,用于向Flutter客户端发送事件 func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { self.eventSink = events return nil } //FlutterStreamHandler协议所必需的 //Flutter客户端停止监听事件时被调用 func onCancel(withArguments arguments: Any?) -> FlutterError? { return nil } }
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let _ = MethodChannelDemo(messenger: controller.binaryMessenger)
import Flutter import UIKit public class MethodChannelDemo { var channel:FlutterMethodChannel init(messenger: FlutterBinaryMessenger) { //与flutter建立通道 "com.flutter.guide.MethodChannel"的通道命名要与flutter一致 channel = FlutterMethodChannel(name: "com.flutter.guide.MethodChannel", binaryMessenger: messenger) //接收来自flutter传过来的值。 'sendData'的方法命名与flutter要一致 channel.setMethodCallHandler { (call:FlutterMethodCall, result:@escaping FlutterResult) in//flutter call ios if (call.method == "dumpViewController") { let viewController = ViewController() if let rootViewController = UIApplication.shared.keyWindow?.rootViewController { rootViewController.present(viewController, animated: true, completion: nil) } } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。