Постоянство данных реактивного интерфейса пользователя - PullRequest
0 голосов
/ 14 декабря 2018

Может кто-нибудь помочь мне с некоторыми указаниями о том, как реализовать постоянство данных в приложении форм Xamarin с использованием UWP и iOS?Я нашел несколько примеров в Интернете, но они довольно старые и ссылаются только на iOS и Android Xamarin Native.В основном я хочу взять модель представления текущей страницы и сохранить все введенные пользователем данные.

AkavacheSuspensionDriver

namespace NameSpace    {
public class AkavacheSuspensionDriver<TAppState> : ISuspensionDriver where TAppState : class
{
    private const string appStateKey = "AppBootstrapper";

    public IObservable<Unit> InvalidateState()
    {
        var result = BlobCache.UserAccount.InvalidateObject<TAppState>(appStateKey);
        return result;
    }

    public IObservable<object> LoadState()
    {
        var result = BlobCache.UserAccount.GetObject<TAppState>(appStateKey);
        return result;
    }

    public IObservable<Unit> SaveState(object state)
    {
        var result = BlobCache.UserAccount.InsertObject(appStateKey, (TAppState)state);
        return result;
    }
}

App.cs

 RxApp.SuspensionHost.CreateNewAppState = () => new AppBootstrapper();
 RxApp.SuspensionHost.SetupDefaultSuspendResume(new 
 AkavacheSuspensionDriver<AppBootstrapper>());

 MainPage = RxApp.SuspensionHost.GetAppState<AppBootstrapper>().CreateMainPage();

Здесь MainPage попытаетсяизвлечь «что-то» из кеша, но это просто бомбы, из которых ничего не выйдет.Нужно ли мне самому заниматься десериализацией и обработкой данных?Я ожидал, что сначала будет создан новый AppBootstrapper по умолчанию.

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Так что я не уверен, что я чувствую по этому поводу, но я нашел решение своей проблемы.Я обнаружил, что SuspensionHost создает AppState самостоятельно.Затем он берет сохраненные данные и повторно гидратирует все, что вы хранили.Чтобы использовать это, я должен был сделать следующее

    public App()
    {
        InitializeComponent();
        try
        {
            RxApp.SuspensionHost.CreateNewAppState = () =>
            {
                return new AppBootstrapper();
            };

            RxApp.SuspensionHost.SetupDefaultSuspendResume(new AkavacheSuspensionDriver<AppBootstrapper>());

            RxApp.SuspensionHost.ObserveAppState<AppBootstrapper>().Subscribe<AppBootstrapper>((a) =>
            {
                Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
                {
                    var bootstrapper = a;
                    MainPage = bootstrapper.CreateMainPage();
                });
            });

            AppCenterLog.Info("Start", "Application Started");
        }
        catch (Exception ex)
        {
            //Crash reporting not available in appcenter - using event analytics as temp solution
            Analytics.TrackEvent("Bootstrap Runtime Error", new Dictionary<string, string> {
                { "Exception", ex.Message }
            });
        }
    }

Итак, в конце приложение загрузится, отобразит пустой экран, а затем узел приостановки создаст новый AppBootloader, заполнит сохраненные данные,и обновите AppState.Используя это новое состояние приложения, я могу затем установить MainPage.

В AppBootLoader я сохраняю только следующее как Datamember

    [DataMember]
    public ICollection<NavStackPersistence> NavStack
    {
        get
        {
            ICollection<NavStackPersistence> navStack = new List<NavStackPersistence>();
            foreach (var vm in Router.NavStackPersistence)
            {
                navStack.Add(new NavStackPersistence()
                {
                    Path = vm.UrlPathSegment,
                    Name = vm.ToString(),
                    ViewModel = (LoginViewModel)vm
                });
            }

            return navStack;
        }

        set
        {
            if (value != null)
            {
                foreach (var vm in value)
                {
                    this.Router
                       .NavigateAndReset
                       .Execute(vm.ViewModel)
                       .Subscribe();
                }
                // TODO in here we set the router path??
            }
        }
    }

И, наконец, класс, который я сохраняю

public class NavStackPersistence
{
    public string Name { get; set; }
    public string Path { get; set; }
    public LoginViewModel ViewModel { get; set; }
}

Это успешно загрузит AppBootloader, заполнит NavStack коллекцией, и каждый элемент в этой коллекции (сейчас только loginViewModel) также будет инициализирован и повторно гидратирован.Мой пример здесь Предоставляет Имя и полностью заполненный LoginViewModel, который при переходе к нему все равно сохранит имя пользователя и пароль, которые были использованы.

Кто-нибудь из команды ReactiveUI имеет какие-либо комментарии о том, как это реализовано?Есть ли лучший способ приблизиться к этому?

Кстати.Любой, кто хочет использовать это для UWP в xamarin, должен был добавить это в файл класса UWP App.CS.

    private AutoSuspendHelper autoSuspendHelper;

    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    public App()
    {
        autoSuspendHelper = new AutoSuspendHelper(this);
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    /// <summary>
    /// Invoked when the application is launched normally by the end user.  Other entry points
    /// will be used such as when the application is launched to open a specific file.
    /// </summary>
    /// <param name="args">Details about the launch request and process.</param>
    protected override void OnLaunched(LaunchActivatedEventArgs args)
    {
        autoSuspendHelper.OnLaunched(args);

        ....
    }
0 голосов
/ 14 декабря 2018

Много разных решений.Одним из них будет проект ReactiveUI под названием akavache.Это позволит вам сохранить ваши данные.Вы можете смешивать их с AutoSuspendHelper https://reactiveui.net/docs/handbook/data-persistence/

Имейте в виду, что наша документация по сохранению данных находится в стадии разработки.Мы пытаемся удалить все разговоры в чате из нашей документации.

...