我需要从原生IOS端发送一些数据到dart端。我正在使用 Channel Method 从 IOS 端调用该方法,但我注意到:
颤动面:
static const platform = const MethodChannel('samples.flutter.dev/battery');
platform.setMethodCallHandler(myUtilsHandler); // I am calling it in initState
Future<dynamic> myUtilsHandler(MethodCall methodCall) async {
print("myUtilsHandler");
switch (methodCall.method) {
case "someMethod":
print(json.decode(methodCall.arguments));
break;
case 'someMethod2':
print("someMethod2");
break;
default:
print("default");
}
}
原生IOS端:
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",binaryMessenger: controller.binaryMessenger)
batteryChannel.invokeMethod("someMethod", arguments: "someValue")
注意:反过来也可以正常工作!
我已经测试过了。 一般来说,使用
FlutterMethodChannel
实例调用 invokeMethod
。
现在我展示一些基于batteryChannel demo的测试代码。
在AppDelegate中添加一个属性
//didFinishLaunchingWithOptions methods
var batteryChannel : FlutterMethodChannel!
batteryChannel = FlutterMethodChannel.init(name: "samples.flutter.dev/battery", binaryMessenger: controller.binaryMessenger)
private func receiveBatteryLevel(result: FlutterResult) {
let device = UIDevice.current;
device.isBatteryMonitoringEnabled = true;
//test send message
sendMessageToFlutter()
if (device.batteryState == UIDevice.BatteryState.unknown) {
result(FlutterError.init(code: "UNAVAILABLE",
message: "Battery info unavailable",
details: nil));
} else {
result(Int(device.batteryLevel * 100));
}
}
private func sendMessageToFlutter(){
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
self.batteryChannel.invokeMethod("nativeCallSomeFlutterMethod", arguments: nil)
}
}
现在在 flutter 方面,也基于
batteryChannel demo
class _MyHomePageState extends State<MyHomePage> {
static const platform = const MethodChannel('samples.flutter.dev/battery');
void initState(){
super.initState();
platform.setMethodCallHandler((call) {
print("init state setMethodCallHandler ${call.method}");
});
}
}
点击
Get Battery Level
按钮后,2秒后,您可以看到
init state setMethodCallHandler nativeCallSomeFlutterMethod
从 Dart 2.18 开始,您还可以使用 Dart 的外部函数接口(FFI)直接调用 Objective-C 和 Swift 代码。
您可以使用方法通道在 Flutter 和 iOS 原生代码之间进行数据通信。在这里,我将向您解释如何使用 Flutter 代码中的 invoke 方法将数据作为参数传递,并在 iOS 原生代码中处理该方法。
第 1 步: 首先,在 dart 文件中创建方法通道名称。
您可以使用方法通道在 Flutter 和 iOS 原生代码之间进行数据通信。在这里,我将向您解释如何使用 Flutter 代码中的 invoke 方法将数据作为参数传递,并在 iOS 原生代码中处理该方法。
static const MethodChannel _channel = const MethodChannel('method_channel_ios');
第 2 步:创建一个调用方法,将参数从 Flutter 传递到 iOS Native。
var returnValue = await _channel.invokeMethod("additionnumbers", <String, dynamic>{
'n1': 10,
'n2': 20,
});
完整代码(Flutter)main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Method Channel',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueAccent),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Method Channel'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const MethodChannel _channel = const MethodChannel('method_channel_ios');
int result = 0;
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("$result",style: const TextStyle(fontSize: 16)),
ElevatedButton(
onPressed: (){
callAdditionNumbers();
},
child: const Text('Get Result'),
),
],
),
),
);
}
void callAdditionNumbers() async {
var returnValue = await _channel.invokeMethod("additionnumbers", <String, dynamic>{
'n1': 10,
'n2': 20,
});
print("RESULT $returnValue");
setState(() {
result = returnValue["Addition"];
});
}
}
iOS端代码实现
第 3 步: 声明方法通道名称与您在 Flutter 端已定义的名称相同。打开 AppDelegate.swift 文件。
let myChannnel = FlutterMethodChannel(
name: "method_channel_ios",
binaryMessenger: controller.binaryMessenger)
第 4 步: 在 AppDelegate.swift 文件中设置调用处理程序的方法
myChannnel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
})
完整代码(Swift)AppDelegate.swift
import Flutter
import UIKit
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let myChannnel = FlutterMethodChannel(
name: "method_channel_ios",
binaryMessenger: controller.binaryMessenger)
myChannnel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
if(call.method == "additionnumbers"){
let c: Int = self.multiplyNumber(call: call) // function is written separately
let finalResult: [String: Int] = ["Addition" : c]
result(finalResult)
}else{
result(FlutterMethodNotImplemented)
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func multiplyNumber(call: FlutterMethodCall) -> Int {
let args = call.arguments as? Dictionary<String, Any>
let a = args?["n1"] as! Int
let b = args?["n2"] as! Int
print(a as Int)
print(b as Int)
let c = a + b
return c;
}
}
要接收来自 iOS 原生 Flutter 的响应,您可以通过完整示例实现适用于 iOS 的 Flutter 方法通道回调。