Próbuję użyć Fluttera do napisania aplikacji mobilnej. Niestety, muszę zaimplementować wtyczkę Flutter, aby móc wywoływać niektóre rodzime API.
Objective-C jest dla mnie zbyt obcy, więc naprawdę wolę używać Swift (którego również nie znam, ale jest wystarczająco blisko Kotlina, że czuję się z nim zaznajomiony), aby utworzyć wtyczkę.
Dostałem konfigurację szkieletu wtyczki przez Flutter, ale teraz próbuję zaimplementować funkcję obsługi metody:
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult)
Natywna funkcja, której próbuję użyć, ma tę sygnaturę (wygenerowaną za pomocą gomobile):
FOUNDATION_EXPORT MobileapiDatabase* MobileapiReadDatabase(
NSString* filePath, NSString* password, NSError** error);
Nie rozumiem jednak kilku rzeczy:
- jak zwrócić błąd za pomocą
result
obiekt? - jak zgłosić metodę nie jest zaimplementowana?
- jak korzystać z funkcji natywnych
error
obiekt?
Mogę tylko znaleźć przykłady Objective-C, a nie pojedynczą próbkę Swift, która pojawiła się wokół Googlinga (jedyna znaleziona próbka nie obsługiwała błędów ani niczego innego).
Oto, co do tej pory osiągnąłem:
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
}
}
Naprawdę doceniam każdą pomoc.
Odpowiedzi:
1 dla odpowiedzi № 1Udało mi się samemu to zrozumieć, czytając kilka przykładów kodu Swift wywołującego Objective-C i sprawdzającego źródła Objective-C.
Oto jak go zaimplementowałem:
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)
}
}
}
Sugestie dotyczące ulepszeń są mile widziane!