【问题标题】:How can i connect Swift file and dart file?如何连接 Swift 文件和 dart 文件?
【发布时间】:2021-07-08 07:32:13
【问题描述】:

我正在连接 Flutter 和 Swift,以便我可以通过连接仅在 Swift 中工作的公共证书 API 在 Flutter 中使用它。但是,我有一个问题,我想问一个问题。

我想要做的是通过一个通道将一个 Swift 函数导入到 main.dart 中,以便在 main.dart 中按下按钮时 Swift 代码可以工作

如何将 Tilko.swift 中的 func 转换为 main.dart

这是结构 enter image description here

main.dart 位于 ios/lib 文件夹,Tilko.swift 位于 ios/Runner

【问题讨论】:

  • 您愿意分享您的MethodChannel("..").invokeMethod 编码
  • 静态 const MethodChannel _channel = const MethodChannel('hem_cert_copy_plugin');

标签: flutter plugins


【解决方案1】:

应该有一个FlutterMethodChannel.swift 它看起来像

class MethodChannelFlutter {
    var controller: FlutterViewController
    var printerChannel: FlutterMethodChannel
    init(controller: FlutterViewController) {
        self.controller = controller
        printerChannel = FlutterMethodChannel(name: "hem_cert_copy_plugin", binaryMessenger: controller.binaryMessenger)

        printerChannel.setMethodCallHandler {
            (call: FlutterMethodCall, _: @escaping FlutterResult) -> Void in
             //Your handler
             //...

你的 AppDelegate.swift 应该是这样的

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
         MethodChannelFlutter(controller: controller)
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

【讨论】:

    【解决方案2】:

    我在这里创建了一个工作示例 https://github.com/theamorn/flutter-template

    在这个文件中,我有 3 种连接到 Native SDK 的方式

    1. 立即调用 Native 并返回值
    2. 调用 Native 并传递给函数并从该函数返回
    3. 调用 Native 并等待委托回调,以便我们可以回调到 Flutter

    首先你在 iOS 中添加 Flutter Channel https://github.com/theamorn/flutter-template/blob/main/ios/Runner/AppDelegate.swift

    private func initFlutterChannel() {
      // com.theamorn.flutter can change to whatever you want, just have to be the same between Flutter and iOS and unique ‘domain prefix. just com.theamorn is not enough
      if let controller = window?.rootViewController as? FlutterViewController {
        let channel = FlutterMethodChannel(
            name: methodChannel,
            binaryMessenger: controller.binaryMessenger)
        
        channel.setMethodCallHandler({ [weak self] (
            call: FlutterMethodCall,
            result: @escaping FlutterResult) -> Void in
            switch call.method {
            case "methodNameOne":
                if let data = call.arguments as? String {
                    self?.callNativeSDK(data)
                } else {
                    result(FlutterMethodNotImplemented)
                }
            case "deviceHasPasscode":
                result(self?.isDeviceHasPasscode)
                
            case "returnValue":
                if let data = call.arguments as? String {
                    self?.returnValueSDK(result: result, id: data)
                } else {
                    result(FlutterMethodNotImplemented)
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        })
      }
    }
    

    methodNameOne 用于调用 Native 函数,其名称应在 Flutter 中保持一致

    private func callNativeSDK(_ id: String) {
        // You can put any Native SDK in here, if the result return from Delegate
        let sdk = ThirdPartySDK(delegate: self, id: id)
        sdk.start()
    }
    
    private func returnValueSDK(result: FlutterResult, id: String) {
        // You can call any SDK in here if the result return immediately
        let sdk = ThirdPartySDK(delegate: self, id: id)
        return result(sdk.process())
    }
    

    使用这个从 Flutter 调用 https://github.com/theamorn/flutter-template/blob/main/lib/main.dart

    final channel = MethodChannel('com.theamorn.flutter');
    try {
        await channel.invokeMethod('methodNameOne', "12345");
    } on PlatformException catch (e) {
        debugPrint("==== Failed to get data '${e.message}' ====");
    }
    

    从 Native 回调到 Flutter,我在 mocking SDK 的 Delegate 中调用这个函数

    extension AppDelegate: ThirdPartySDKDelegate {
        
        func onFinish(value: String) {
            // You can send anything into arguments, String, Boolean, or even Dictionary
            // Send data back to Flutter
            if let controller = self.window?.rootViewController as? FlutterViewController {
                let channel = FlutterMethodChannel(
                    name: methodChannel,
                    binaryMessenger: controller.binaryMessenger)
                channel.invokeMethod("methodNameTwoFromSDK", arguments: value)
            }
        }
        
    }
    

    等待来自 Native 的值

    _waitingDataFromNative() async {
        channel.setMethodCallHandler((call) async {
          // Receive data from Native
          switch (call.method) {
            case "methodNameTwoFromSDK":
              _nativeValue = call.arguments;
              setState(() {});
              break;
            default:
              break;
          }
        });
      }
    

    您在 iOS 中看到该方法名称,Flutter 需要完全相同,否则它们无法看到彼此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 2019-05-16
      • 2014-06-01
      • 1970-01-01
      • 2010-10-29
      相关资源
      最近更新 更多