I'm creating a Flutter plugin with some native iOS ViewController
from a native iOS app.
In the native ViewController
I setup a MethodChannel
and a MethodCallHandler
, same in the Flutter screen.
I'm using the StandartMessageCodec
in both UIKitView
and FlutterPlatformViewFactory
which should support most iOS object types:
/// On iOS, messages are represented as follows: /// /// * null: nil /// * [bool]:
NSNumber numberWithBool:
/// * [int]:NSNumber numberWithInt:
for values that are representable using /// 32-bit two's complement;NSNumber numberWithLong:
otherwise /// * [double]:NSNumber numberWithDouble:
/// * [String]:NSString
/// * [Uint8List], [Int32List], [Int64List], [Float64List]: ///FlutterStandardTypedData
/// * [List]:NSArray
/// * [Map]:NSDictionary
When i use the invokeMethod:argument:result
method from iOS dough, I do get its arguments across to Flutter, but the result callback in iOS is a FlutterError :
pluginChannel.invokeMethod("retrieve_data", arguments: ["selectedVehicleType": selectedVehicleType] as! Any) { (r: Any) in
print("@@ result from retrieve_data method call is: \(r)")
if let error = r as? FlutterError {
print("error is : \n\(error.code), \n\(error.message)")
}
}
error is : error, Optional("type '_Map<Object?, Object?>' is not a subtype of type 'Future'")
MethodChannel handler in Flutter:
channel.setMethodCallHandler((call) {
switch (call.method) {
// test call for getting data from API
// this is invoked with "result" parameter on native side which returns an error:
// "type \'_Map<Object?, Object?>\' is not a subtype of type \'Future<dynamic>\'"
case 'retrieve_data':
print(
'## retrieve_data received in NativeScreenExample with args \n ${call.arguments}, \n of type ${call.arguments.runtimeType}');
// test invocation to send data from API to native
dynamic result =
channel.invokeMethod('data_retrieved', 'arg').then((result) {
print(
'## data_retireved method invoked with result data from native: $result');
return result;
});
break;
default:
}
return call.arguments;
});
Can you spot something wrong with the setup?
I think, that handler
(it is the callback you set in setMethodCallHandler
) should return Future
to MethodChannel
correct work.
To achieve this, you should add async
keyword like this:
channel.setMethodCallHandler((call) async {
// your actual code here
}
After that change I could achieve Success: ["selectedVehicleType": Car]
(I used "Car"
as "selectedVehicleType") in my log in Xcode.
Hope this helps!