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!