如何在Swift中实现FlutterPlugin的方法处理程序?

时间:2018-04-28 16:55:13

标签: swift flutter

我正在尝试使用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对象?
  4. 我只能找到Objective-C示例,而不是通过Google搜索引发的单个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
      }
    }
    

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分: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)
        }
    }
}

欢迎提出改进建议!