【问题标题】:How to implement a FlutterPlugin's method handler in Swift?如何在 Swift 中实现 FlutterPlugin 的方法处理程序?
【发布时间】:2018-04-28 16:55:13
【问题描述】:

我正在尝试使用 Flutter 编写移动应用程序。不幸的是,我需要实现一个 Flutter 插件才能调用一些原生 API。

Objective-C 对我来说太陌生了,所以我真的更喜欢使用 Swift(我也不太了解,但它与 Kotlin 足够接近,我觉得很熟悉)来创建插件。

我通过 Flutter 获得了插件骨架设置,但现在我正在尝试实现方法处理函数:

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult)

我尝试使用的本机函数具有此签名(使用 gomobile 生成):

FOUNDATION_EXPORT MobileapiDatabase* MobileapiReadDatabase(
  NSString* filePath, NSString* password, NSError** error);

虽然有几件事我不明白:

  1. 如何使用result 对象返回错误?
  2. 方法没实现怎么报?
  3. 如何使用原生函数的error对象?

我只能找到 Objective-C 示例,没有一个通过谷歌搜索找到的 Swift 示例(我发现的唯一示例没有处理错误或其他任何内容)。

这是我目前得到的:

public func handle(_ call: FlutterMethodCall, 
    result: @escaping FlutterResult) {
  switch call.method {
  case "getDb":
    let args = call.arguments as! [String]
    if args.count == 2 {
        let error = NSError() // ERROR in next line
        MobileapiReadDatabase(args[0], args[1], error)
        // how to check if there was an error?
    }
    // TODO report wrong arguments
  default:
    // TODO report method not implemented
  }
}

非常感谢任何帮助。

【问题讨论】:

    标签: swift flutter


    【解决方案1】:

    通过阅读一些调用 Objective-C 的 Swift 代码示例并检查 Objective-C 源代码,我自己设法弄明白了。

    我是这样实现的:

    import Flutter
    import UIKit
    import Mobileapi
    
    public class SwiftGohashMobilePlugin: NSObject, FlutterPlugin {
        public static func register(with registrar: FlutterPluginRegistrar) {
            let channel = FlutterMethodChannel(name: "gohash_mobile", binaryMessenger: registrar.messenger())
            let instance = SwiftGohashMobilePlugin()
            registrar.addMethodCallDelegate(instance, channel: channel)
        }
    
        public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
            switch call.method {
            case "getDb":
                if let args = call.arguments as? [String] {
                    if args.count == 2 {
                        var error : NSError?
                        let db = MobileapiReadDatabase(args[0], args[1], &error)
                        if let errorMessage = error?.userInfo.description {
                            result(FlutterError.init(code: "NATIVE_ERR",
                                                     message: "Error: " + errorMessage,
                                                     details: nil))
                        } else {
                            // SUCCESS!!
                            result(db!)
                        }
                    } else {
                        result(FlutterError.init(code: "BAD_ARGS",
                                                 message: "Wrong arg count (getDb expects 2 args): " + args.count.description,
                                                 details: nil))
                    }
                } else {
                    result(FlutterError.init(code: "BAD_ARGS",
                                             message: "Wrong argument types",
                                             details: nil))
                }
            default:
                result(FlutterMethodNotImplemented)
            }
        }
    }
    

    欢迎提出改进建议!

    【讨论】:

      猜你喜欢
      • 2014-09-20
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多