• Flutter-使用MethodChannel 实现与iOS交互


    前言

    使用 MethodChannel 在 Flutter 与原生 Android 和 iOS 之间进行通信,可以让你在 Flutter 应用中调用设备的原生功能。

    基础概念

    • MethodChannel:Flutter 提供的通信机制,允许消息以方法调用的形式在 Flutter 与原生代码之间传递。
    • 方法调用:从 Flutter 向原生或从原生向 Flutter 发送一个方法名和参数,接收方执行相应操作后,可以返回结果。

    在 Flutter 中的实现

    定义 MethodChannel
    首先,在 Flutter 中定义一个 MethodChannel,传入一个与原生端约定的通道名称。

       import 'package:flutter/services.dart';
    
       class NativeBridge {
         static const MethodChannel _channel = MethodChannel('com.example.myapp/channel');
       
         static Future getPlatformVersion() async {
           final String? version = await _channel.invokeMethod('getPlatformVersion');
           return version;
         }
       }
    

    调用方法
    使用 _channel.invokeMethod 方法调用原生方法。传入方法名(与原生端约定)及需要的参数。
    调用示例:
    在这里插入图片描述

    iOS 上的实现(Swift)

    在 iOS 项目中设置 MethodChannel
    在 AppDelegate.swift 中设置 MethodChannel

    import UIKit
    import Flutter
    
    @UIApplicationMain
    @objc class AppDelegate: FlutterAppDelegate {
      private let CHANNEL = "com.example.myapp/channel"
    
      override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
        
        // 获取根视图控制器
        guard let controller = window?.rootViewController as? FlutterViewController else {
          fatalError("Root view controller is not a FlutterViewController")
        }
       // 创建方法通道
        let methodChannel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger)
        methodChannel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
          
          // 处理定义的方法
          if call.method == "getPlatformVersion" {
            result("iOS" + UIDevice.current.systemVersion)
          } else {
            result(FlutterMethodNotImplemented)
          }
        }
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
      }
    }
    

    运行iOS设备查看效果
    可以看到我们通过getPlatformVersion 成功获取到了系统版本号
    在这里插入图片描述

    封装通信管理类

    NativeChannelManager

    import 'package:flutter/services.dart';
    
    /// NativeChannelManager 类是单例模式,用于与原生代码进行通信。
    class NativeChannelManager {
      // 私有构造函数确保类的单例性
      NativeChannelManager._();
    
      // 单例对象
      static final NativeChannelManager _instance = NativeChannelManager._();
    
      // 提供一个访问单例的方法
      static NativeChannelManager get instance => _instance;
    
      // MethodChannel 实例
      final MethodChannel _channel = const MethodChannel('com.example.myapp/channel');
    
      // 获取平台版本
      Future getPlatformVersion() async {
        try {
          final String? version = await _channel.invokeMethod('getPlatformVersion');
          return version;
        } on PlatformException catch (e) {
          // 可以在这里添加更复杂的错误处理逻辑
          print("获取平台版本失败: '${e.message}'");
          // 还可以选择抛出错误、记录日志或执行其他错误处理措施
          return null;
        }
      }
    
      // 在这里可以继续添加更多与原生交互的方法
    }
    

    调用示例:

     void _getPlatformVersion() async {
        // 调用 NativeChannelManager 的 getPlatformVersion 方法
        String? platformVersion = await NativeChannelManager.instance.getPlatformVersion();
        // 打印返回值
        print("platformVersion: $platformVersion");
       }
    

    调用时机
    最好在 Flutter 的 Widget 生命周期的合适时机(如 initState)调用原生方法,确保当界面准备好的时候,原生数据也准备就绪。

    注意事项

    • 确保 Flutter 与原生两端约定好的通道名称和方法名称一致,避免通信失败。
    • 对于可能出现的任何异步操作,务必处理原生代码中可能出现的异常,并在 Dart 中恰当地对 Future 结果进行处理。
    • 通信的数据类型,需要各平台都支持的类型,最好都统一成String。

    结语

    通过以上步骤,你已经掌握了如何在 Flutter 应用中使用 MethodChannel 与 iOS 代码进行通信。这种方法不仅能帮助你充分利用设备的原生功能,还能提升应用的性能和用户体验。无论是调用相机、获取位置信息,还是其他复杂的原生操作,MethodChannel 都能为你提供一个简洁高效的解决方案。希望这篇指南能为你的 Flutter 开发之旅增添一份助力,让你在跨平台开发的道路上更加游刃有余。Happy coding!

  • 相关阅读:
    Anaconda虚拟环境下导入opencv
    Lagging issues of Ubuntu 20.04 on VMWare Player(卡顿问题)
    PHP LFI 利用临时文件Getshell
    什么是时钟树综合?
    【课程作业】西瓜书 机器学习课后习题 : 第二章
    【算法刷题日记之本手篇】统计每个月兔子的总数与字符串通配符
    【IDEA】-使用IDEA查看类之间的依赖关系
    【升级U8+】为视图或函数 ‘Ap_DetailVend‘ 指定的列名比其定义中的列多。
    微信小程序使用echarts/数据刷新重新渲染/图层遮挡问题
    亚马逊新手运营需要规避哪些风险?怎么分析竞争对手?——站斧浏览器
  • 原文地址:https://blog.csdn.net/lyh1083908486/article/details/139628122