0

I wrote an interface and android implementation for counting steps using Android SensorService. Now I'm trying to do the same for iOS. I can't find any code examples about this topic apart from this https://github.com/xamarin/ios-samples/blob/master/PrivacyPrompts/PrivacyPrompts/PrivacyManager/MotionPrivacyManager.cs which returns the number of steps between two time intervals. But I need to monitor step count in the real time. Or close to it. Android SensorService has some delay, but it's doing it in the real time. I need to do the same for iOS. Is there a way to do in in iOS?

Maybe I need to make a time window of 2 time frames and try to monitor data this way? But the time frame could be very small, from a second to 5 minutes. Will it even work?

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 ();
    }
}
irondsd
  • 1,140
  • 1
  • 17
  • 34
  • https://github.com/MikeCodesDotNET/My-StepCounter – Jason Jan 28 '19 at 22:17
  • As far as I understand, it's almost the same code as I mentioned and it doesn't count in the real time. Or does it? – irondsd Jan 28 '19 at 23:00
  • I didn't review the code, I was just pointing it out as an example. I assume it does live updates - it would be easy to install and test to verify. – Jason Jan 28 '19 at 23:18
  • there is a good discussion of the underlying APIs here: https://www.cocoanetics.com/2014/03/m7-pedometer/ – Jason Jan 29 '19 at 00:31

0 Answers0