Пожалуйста, укажите мне правильное направление, чтобы понять, как работать в фоновом режиме в iOS - PullRequest
0 голосов
/ 10 февраля 2020

Я работаю над фитнес-приложением (использующим Xamarin) и хотел бы, чтобы оно продолжало работать в фоновом режиме, если пользователь переключается на другое приложение или нажимает боковую кнопку, чтобы закрыть экран. Я просмотрел несколько учебных пособий, включая этот https://robgibbens.com/backgrounding-with-xamarin-forms/, который показался мне очень многообещающим. Однако при запуске моего приложения и переключении на другое приложение или при отключении экрана мое приложение просто приостанавливается. Ее код iOS speci c запускает фоновую задачу:

public class IOSPlayWorkoutTask
{
    nint _taskID;
    CancellationTokenSource _cts;
    Workout _workout;

    public async Task Start()
    {
        _cts = new CancellationTokenSource();
        _taskID = UIApplication.SharedApplication.BeginBackgroundTask("IOSPlayWorkoutTask", OnExpiration);

        try
        {
            WorkoutPlayer.Shared.Workout = _workout;
            await WorkoutPlayer.Shared.PlayWorkout(_cts.Token);
        }
        catch (OperationCanceledException)
        {
        }
        finally
        {
            if (_cts.IsCancellationRequested)
            {
                //Device.BeginInvokeOnMainThread(
                //    () => MessagingCenter.Send(new CancelPlayingWorkoutMessage(), CancelPlayingWorkoutMessage.MessageText));
            }
        }

        UIApplication.SharedApplication.EndBackgroundTask(_taskID);
    }

    public void Pause()
    {
        WorkoutPlayer.Shared.RequestPause();
        _cts.Cancel();
        Device.BeginInvokeOnMainThread(
            () => MessagingCenter.Send(new PausedWorkoutMessage(), PausedWorkoutMessage.MessageText));
    }

    public void Stop()
    {
        _cts.Cancel();
        Device.BeginInvokeOnMainThread(
            () => MessagingCenter.Send(new FinishedWorkoutMessage(), FinishedWorkoutMessage.MessageText));
    }

    void OnExpiration()
    {
        _cts.Cancel();
    }

    public IOSPlayWorkoutTask(Workout w)
    {
        _workout = w;
    }
}

Делегат приложения iOS регистрируется для получения сообщений, одно из которых запускает задачу выше. Я знаю, что, должно быть, мне чего-то очень не хватает c. Любая помощь будет принята с благодарностью. Я знаю, что это должно быть возможно на основе моего опыта использования других фитнес-приложений, таких как Couch to 5k.

1 Ответ

0 голосов
/ 10 февраля 2020

Спасибо @sushihangover и @ Paulw11 за ваш вклад. Похоже, секрет заключается в добавлении обработчика в BeginBackgroundTask, который вызывает EndBackgroundTask. Не уверен, что я полностью понимаю на данный момент, но, очевидно, это создает у iOS впечатление, что вы «хороший гражданин», но продолжает выполнять свою задачу. Вот мой код, который работает:

    public async Task Start()
    {
        _cts = new CancellationTokenSource();
        //_taskID = UIApplication.SharedApplication.BeginBackgroundTask("IOSPlayWorkoutTask", OnExpiration);
        _taskID = UIApplication.SharedApplication.BeginBackgroundTask(() =>
        {
            Console.WriteLine("Guess my time is up");
            UIApplication.SharedApplication.EndBackgroundTask(_taskID);
        });
            try
            {
                WorkoutPlayer.Shared.Workout = _workout;
                await WorkoutPlayer.Shared.PlayWorkout(_cts.Token);
                //finished = true;
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("OperationCanceledException");
                //finished = true;
            }
            finally
            {
                if (_cts.IsCancellationRequested)
                {
                    //Device.BeginInvokeOnMainThread(
                    //    () => MessagingCenter.Send(new CancelPlayingWorkoutMessage(), CancelPlayingWorkoutMessage.MessageText));
                }
            }
        UIApplication.SharedApplication.EndBackgroundTask(_taskID);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...