ReactiveUI: [BUG] XF RefreshView and ReactiveCommand does not get along on iOS

Describe the bug I modified the official Xamarin Forms RefreshView demo ever so slightly, replacing the ICommand with a ReactiveCommand, and the demo broke.

Specifically, pull-to-refresh will run once, and then never again.

I’m not entirely sure what goes on, but it feels like the thread the command is running on returns to the caller as soon as the awaited method RefreshItemsAsync reached called, rather than after the method has completed, as would be expected.

I’ve used ReactiveCommand’s in many instances and never seen this behavior, and believe that there’s a bug with either ReactiveCommand or RefreshView. In the case of the later, maybe, someone here could point me in the direction of a course, and I will happily file a bug with XF.

Steps To Reproduce Please see this repro, with the slight change to the official demo: https://github.com/1iveowl/RxUI.RefreshView.Repro/tree/master/src/RefreshViewDemo

Expected behavior Pull-to-refresh would work more than once.

Environment

  • OS: iOS 13.3
  • Version ReactiveUI 11.1.1
  • Device: iOS Simulator and iPad 10,5"

Code with modification

public class MainPageViewModel : ReactiveObject, INotifyPropertyChanged
    {
        const int RefreshDuration = 2;
        int itemNumber = 1;
        readonly Random random;
        bool isRefreshing;

        public bool IsRefreshing
        {
            get { return isRefreshing; }
            set
            {
                isRefreshing = value;
                OnPropertyChanged();
            }
        }

        public ObservableCollection<Item> Items { get; private set; }

        
        // Replaced:
        //public ICommand RefreshCommand => new Command(async () => await RefreshItemsAsync());

        // Replacement:
        private ReactiveCommand<Unit, Unit> _refreshCommand;

        public ReactiveCommand<Unit, Unit> RefreshCommand
        {
            get => _refreshCommand;
            set => this.RaiseAndSetIfChanged(ref _refreshCommand, value);
        }


        public MainPageViewModel()
        {
            random = new Random();
            Items = new ObservableCollection<Item>();
            AddItems();

            // Added
            DefineRefreshCommandCommand();
        }

        void AddItems()
        {
            for (int i = 0; i < 50; i++)
            {
                Items.Add(new Item
                {
                    Color = Color.FromRgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)),
                    Name = $"Item {itemNumber++}"
                });
            }
        }


        //Added
        private void DefineRefreshCommandCommand()
        {
            RefreshCommand = ReactiveCommand.CreateFromTask<Unit>(async x =>
            {
                await RefreshItemsAsync();
            });

            RefreshCommand.ThrownExceptions.Subscribe(ex => Debug.WriteLine(ex.Message));
        }

        async Task RefreshItemsAsync()
        {
            IsRefreshing = true;
            await Task.Delay(TimeSpan.FromSeconds(RefreshDuration));
            AddItems();
            IsRefreshing = false;
        }

...
    }

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (11 by maintainers)

Most upvoted comments

After some additional looking at this and conversations in slack I had a quick aside with someone on the XF team. This may be an issue in the RefreshView implementation. We are looking into it and will have something to report back early next week.

This is the bug you want to attach to.

https://github.com/xamarin/Xamarin.Forms/issues/9326

@1iveowl Thank You for reporting this, and providing a reproduction. I am going to do my best to look at your reproduction this week.

See the linked issue that @PureWeen attached and maybe link your video there also.

To be clear. This is not an issue with the Xamarin.Forms RefreshView. There is a bug tagged to look into the ReactiveCommand binding. And it seems there was a similar one reported earlier.

If the sample provided doesn’t resolve the ability to interact with the RefreshView, then we should reopen this issue. Otherwise we should talk about what issues we are seeing with the ReactiveCommand bindings on #2316