private void HandleMethodCall(MethodCall call, MethodChannel.IResult result) { // Return an error if Flutter is invoking method calls through method channel // when bridge is configured for WebSocket communication if (Mode == FlutnetBridgeMode.WebSocket) { result.NotImplemented(); return; } // Extract target method information from MethodCall.Method FlutnetMethodInfo methodInfo; Object dartReturnValue; try { methodInfo = JsonConvert.DeserializeObject <FlutnetMethodInfo>(call.Method, FlutterInterop.JsonSerializerSettings); dartReturnValue = FlutterInterop.ToMethodChannelResult(0); } catch (Exception ex) { result.Error(FlutnetErrorCode.OperationNotImplemented.ToString(), ex.Message, null); return; } // Send an empty - successful - response to immediately free Flutter thread result.Success(dartReturnValue); Task.Run(() => { BackgroundHandleMethodCall(methodInfo, call); }); }
private void FlutnetRuntimeOnPlatformEvent(object sender, OnPlatformEventArgs e) { // Prevent dispatching events to Flutter through event channel // if bridge is configured for WebSocket communication if (Mode == FlutnetBridgeMode.WebSocket) { return; } FlutnetEventInfo eventInfo = new FlutnetEventInfo { InstanceId = e.ServiceName, EventName = e.EventName.FirstCharLower(), EventData = e.EventData }; NSObject eventValue = FlutterInterop.ToMethodChannelResult(eventInfo); // As stated here https://docs.microsoft.com/en-US/xamarin/essentials/main-thread#determining-if-code-is-running-on-the-main-thread: // The platform implementations of BeginInvokeOnMainThread themselves check if the call is made on the main thread. // There is very little performance penalty if you call BeginInvokeOnMainThread when it's not really necessary. if (!MainThread.IsMainThread) { MainThread.BeginInvokeOnMainThread(() => { try { _streamHandler.EventSink?.Invoke(eventValue); } catch (Exception ex) { // TODO: Properly log any error Console.WriteLine(ex.Message); } }); } else { try { _streamHandler.EventSink?.Invoke(eventValue); } catch (Exception ex) { // TODO: Properly log any error Console.WriteLine(ex.Message); } } }
private void SendError(FlutnetMethodInfo methodInfo, PlatformOperationException exception) { FlutnetMessage message = new FlutnetMessage { MethodInfo = methodInfo, // NOTE: Please consider removing ErrorCode and ErrorMessage ErrorCode = FlutnetErrorCode.OperationFailed, ErrorMessage = exception.Message, Exception = exception }; NSObject dartReturnValue = FlutterInterop.ToMethodChannelResult(message); Console.WriteLine("Sending error to Flutter..."); MainThread.BeginInvokeOnMainThread(() => _methodChannelIncoming.InvokeMethod("error", dartReturnValue)); }
private void SendResult(FlutnetMethodInfo methodInfo, object result) { Dictionary <string, object> resultValue = new Dictionary <string, object>(); resultValue.Add("ReturnValue", result); FlutnetMessage message = new FlutnetMessage { MethodInfo = methodInfo, Result = resultValue }; NSObject dartReturnValue = FlutterInterop.ToMethodChannelResult(message); Console.WriteLine("Sending result to Flutter..."); MainThread.BeginInvokeOnMainThread(() => _methodChannelIncoming.InvokeMethod("result", dartReturnValue)); }
private void FlutnetRuntimeOnPlatformEvent(object sender, OnPlatformEventArgs e) { // Prevent dispatching events to Flutter through event channel // if bridge is configured for WebSocket communication if (Mode == FlutnetBridgeMode.WebSocket) { return; } FlutnetEventInfo eventInfo = new FlutnetEventInfo { InstanceId = e.ServiceName, EventName = e.EventName.FirstCharLower(), EventData = e.EventData }; Object eventValue = FlutterInterop.ToMethodChannelResult(eventInfo); if (!MainThread.IsMainThread) { MainThread.BeginInvokeOnMainThread(() => { try { _streamHandler.EventSink?.Success(eventValue); } catch (Exception ex) { // TODO: Properly log any error Console.WriteLine(ex.Message); } }); } else { try { _streamHandler.EventSink?.Success(eventValue); } catch (Exception ex) { // TODO: Properly log any error Console.WriteLine(ex.Message); } } }
private void Send(FlutnetMessage message) { try { // OLD VERSION //string json = JsonConvert.SerializeObject(message, FlutterInterop.JsonSerializerSettings); // NEW - FIX ISSUES ABOUT DICTIONARY IN FLUTTER JObject jsonObject = JObject.FromObject(message, FlutterInterop.Serializer); FlutterInterop.CleanObjectFromInvalidTypes(ref jsonObject); string json = jsonObject.ToString(Formatting.None); Send(json); } catch (Exception) { AddToBuffer(message); } }
private void HandleMethodCall(FlutterMethodCall call, FlutterResult callback) { // Return an error if Flutter is invoking method calls through method channel // when bridge is configured for WebSocket communication if (Mode == FlutnetBridgeMode.WebSocket) { callback(ConstantsEx.FlutterMethodNotImplemented); return; } // Extract target method information from MethodCall.Method FlutnetMethodInfo methodInfo; NSObject dartReturnValue; try { methodInfo = JsonConvert.DeserializeObject <FlutnetMethodInfo>(call.Method, FlutterInterop.JsonSerializerSettings); dartReturnValue = FlutterInterop.ToMethodChannelResult(0); } catch (Exception ex) { callback(FlutterError.Create(FlutnetErrorCode.OperationNotImplemented.ToString(), ex.Message, null)); return; } // Send an empty - successful - response to immediately free Flutter thread callback(dartReturnValue); nint[] taskId = new nint[1]; taskId[0] = UIApplication.SharedApplication.BeginBackgroundTask(() => { FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationCanceled); MainThread.BeginInvokeOnMainThread(() => SendError(methodInfo, error)); UIApplication.SharedApplication.EndBackgroundTask(taskId[0]); }); // Run the call in Background Task.Run(() => { BackgroundHandleMethodCall(methodInfo, call); UIApplication.SharedApplication.EndBackgroundTask(taskId[0]); }); }