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);
                }
            }
        }
Example #2
0
        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);
            }
        }