Как считать шаги в реальном времени в iOS с помощью Xamarin - PullRequest
0 голосов
/ 29 января 2019

Я написал интерфейс и реализацию Android для подсчета шагов с помощью Android SensorService.Сейчас я пытаюсь сделать то же самое для iOS.Я не могу найти никаких примеров кода по этой теме, кроме этой https://github.com/xamarin/ios-samples/blob/master/PrivacyPrompts/PrivacyPrompts/PrivacyManager/MotionPrivacyManager.cs, которая возвращает количество шагов между двумя временными интервалами.Но мне нужно следить за количеством шагов в реальном времени.Или близко к этому.Android SensorService имеет некоторую задержку, но делает это в режиме реального времени.Мне нужно сделать то же самое для iOS.Есть ли способ сделать в iOS?

Может быть, мне нужно сделать временное окно из 2-х периодов и попытаться отслеживать данные таким образом?Но временные рамки могут быть очень маленькими, от секунды до 5 минут.Будет ли это вообще работать?

using CoreMotion;
using Foundation;
using UIKit;

namespace PrivacyPrompts
{
public class MotionPrivacyManager : IPrivacyManager, IDisposable
{
    CMStepCounter stepCounter;
    string motionStatus = "Indeterminate";
    nint steps = 0;

    CMMotionManager motionManger; // before iOS 8.0
    CMPedometer pedometer; // since iOS 8.0

    public MotionPrivacyManager ()
    {
        if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
            pedometer = new CMPedometer ();
            motionStatus = CMPedometer.IsStepCountingAvailable ? "Available" : "Not available";
        } else {
            stepCounter = new CMStepCounter ();
            motionManger = new CMMotionManager ();
            motionStatus = motionManger.DeviceMotionAvailable ? "Available" : "Not available";
        }
    }

    public Task RequestAccess ()
    {
        var yesterday = NSDate.FromTimeIntervalSinceNow (-60 * 60 * 24);

        if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
            if(!CMPedometer.IsStepCountingAvailable)
                return Task.FromResult<object> (null);

            return pedometer.QueryPedometerDataAsync (yesterday, NSDate.Now)
                .ContinueWith (PedometrQueryContinuation);
        } else {
            if (!motionManger.DeviceMotionAvailable)
                return Task.FromResult<object> (null);

            return stepCounter.QueryStepCountAsync (yesterday, NSDate.Now, NSOperationQueue.MainQueue)
                .ContinueWith (StepQueryContinuation);
        }

    }

    void PedometrQueryContinuation(Task<CMPedometerData> t)
    {
        if (t.IsFaulted) {
            var code = ((NSErrorException)t.Exception.InnerException).Code;
            if (code == (int)CMError.MotionActivityNotAuthorized)
                motionStatus = "Not Authorized";
            return;
        }

        steps = t.Result.NumberOfSteps.NIntValue;
    }

    void StepQueryContinuation(Task<nint> t)
    {
        if (t.IsFaulted) {
            var code = ((NSErrorException)t.Exception.InnerException).Code;
            if (code == (int)CMError.MotionActivityNotAuthorized)
                motionStatus = "Not Authorized";
            return;
        }

        steps = t.Result;
    }

    public string CheckAccess ()
    {
        return motionStatus;
    }

    public string GetCountsInfo()
    {
        return steps > 0 ? string.Format ("You have taken {0} steps in the past 24 hours", steps) : string.Empty;
    }

    public void Dispose ()
    {
        motionManger.Dispose ();
        stepCounter.Dispose ();
    }
}
...