protected override void OnMessage(MessageEventArgs e) { if (e.Data == null) { return; } if (e.Data != null) { FlutnetMessage request; try { request = JsonConvert.DeserializeObject <FlutnetMessage>(e.Data, FlutterInterop.JsonSerializerSettings); } catch (Exception) { // ignore invalid messages return; } FlutnetRuntime.OperationInfo operation; try { operation = FlutnetRuntime.GetOperation(request.MethodInfo.Instance, request.MethodInfo.Operation); } catch (Exception) { FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationNotImplemented); SendError(request.MethodInfo, error); return; } if (operation.Parameters.Length != request.Arguments.Count) { FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationArgumentCountMismatch); SendError(request.MethodInfo, error); return; } object[] arguments = new object[operation.Parameters.Length]; try { for (int i = 0; i < operation.Parameters.Length; i++) { ParameterInfo param = operation.Parameters[i]; Type paramType = param.IsOut || param.ParameterType.IsByRef ? param.ParameterType.GetElementType() : param.ParameterType; string paramName = param.Name.FirstCharUpper(); object value; if (request.Arguments.ContainsKey(paramName)) { object argumentValue = request.Arguments[paramName]; if (argumentValue == null) { value = null; } else if (argumentValue.GetType() == paramType) { value = argumentValue; } else if (argumentValue is string && paramType != null && paramType.IsEnum) { // Handle enums: remove double quotes from "enumName" string enumString = (argumentValue as string); value = Enum.Parse(paramType, enumString); } else if (paramType != null && argumentValue.GetType().IsPrimitive&& paramType.IsPrimitive) { value = Convert.ChangeType(argumentValue, paramType); } else { JObject jobj = JObject.FromObject(argumentValue); value = jobj.ToObject(paramType); } } else if (param.HasDefaultValue) { value = param.DefaultValue; } else { FlutnetException error = new FlutnetException(FlutnetErrorCode.InvalidOperationArguments); SendError(request.MethodInfo, error); return; } arguments[i] = value; } } catch (Exception) { FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationArgumentParsingError); SendError(request.MethodInfo, error); return; } PlatformOperationResult result = PlatformOperationRunner.Run(operation, arguments); if (result.Error != null) { if (result.Error is PlatformOperationException flutterException) { SendError(request.MethodInfo, flutterException); } else { //In case of an unhandled exception, send to Flutter a verbose error message for better diagnostic FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationFailed, result.Error.ToStringCleared(), result.Error); SendError(request.MethodInfo, error); } } else { SendResult(request.MethodInfo, result.Result); } } }
private void BackgroundHandleMethodCall(FlutnetMethodInfo methodInfo, FlutterMethodCall call) { FlutnetRuntime.OperationInfo operation; try { operation = FlutnetRuntime.GetOperation(methodInfo.Instance, methodInfo.Operation); } catch (Exception) { SendError(methodInfo, new FlutnetException(FlutnetErrorCode.OperationNotImplemented)); return; } NSDictionary dartArguments = call.Arguments as NSDictionary; if (operation.Parameters.Length > 0 && dartArguments == null) { SendError(methodInfo, new FlutnetException(FlutnetErrorCode.OperationArgumentCountMismatch)); return; } object[] arguments = new object[operation.Parameters.Length]; try { for (int i = 0; i < operation.Parameters.Length; i++) { ParameterInfo param = operation.Parameters[i]; Type paramType = param.IsOut || param.ParameterType.IsByRef ? param.ParameterType.GetElementType() : param.ParameterType; NSString paramName = new NSString(param.Name.FirstCharUpper()); object value; if (dartArguments.ContainsKey(paramName)) { NSObject argumentValue = dartArguments[paramName]; NSString serializedArg = (NSString)argumentValue; // Deserialize the arg value value = JsonConvert.DeserializeObject(serializedArg, paramType, FlutterInterop.JsonSerializerSettings); } else if (param.HasDefaultValue) { value = param.DefaultValue; } else { SendError(methodInfo, new FlutnetException(FlutnetErrorCode.InvalidOperationArguments)); return; } arguments[i] = value; } } catch (Exception) { SendError(methodInfo, new FlutnetException(FlutnetErrorCode.OperationArgumentParsingError)); return; } PlatformOperationResult result = PlatformOperationRunner.Run(operation, arguments); if (result.Error != null) { if (result.Error is PlatformOperationException flutterException) { SendError(methodInfo, flutterException); } else { //In case of an unhandled exception, send to Flutter a verbose error message for better diagnostic FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationFailed, result.Error.ToStringCleared(), result.Error); SendError(methodInfo, error); } } else { SendResult(methodInfo, result.Result); } }