如何调用原生IOS中的Method向Flutter发送数据?

问题描述 投票:0回答:3

我需要从原生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")

注意:反过来也可以正常工作!

ios swift flutter dart
3个回答
7
投票

我已经测试过了。 一般来说,使用

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


0
投票

从 Dart 2.18 开始,您还可以使用 Dart 的外部函数接口(FFI)直接调用 Objective-C 和 Swift 代码。

更多信息:https://medium.com/dartlang/dart-2-18-f4b3101f146c


0
投票

您可以使用方法通道在 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 方法通道回调

© www.soinside.com 2019 - 2024. All rights reserved.